mirror of
https://github.com/openharmony/third_party_openhitls.git
synced 2026-07-01 10:05:26 -04:00
openhitls repo init
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
.vscode
|
||||
build
|
||||
__pycache__
|
||||
*/build/*
|
||||
testcode/framework/tls/lib/
|
||||
testcode/output/
|
||||
platform/*
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "platform/Secure_C"]
|
||||
path = platform/Secure_C
|
||||
url = https://gitee.com/openeuler/libboundscheck.git
|
||||
@@ -0,0 +1,28 @@
|
||||
# This file is part of the openHiTLS project.
|
||||
#
|
||||
# openHiTLS is licensed under the Mulan PSL v2.
|
||||
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
# You may obtain a copy of Mulan PSL v2 at:
|
||||
#
|
||||
# http://license.coscl.org.cn/MulanPSL2
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
# See the Mulan PSL v2 for more details.
|
||||
|
||||
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||
|
||||
project(openHiTLS)
|
||||
|
||||
set(HiTLS_SOURCE_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
if(DEFINED BUILD_DIR)
|
||||
set(HiTLS_BUILD_DIR ${BUILD_DIR})
|
||||
else()
|
||||
set(HiTLS_BUILD_DIR ${HiTLS_SOURCE_ROOT_DIR}/build)
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND python3 ${HiTLS_SOURCE_ROOT_DIR}/configure.py -m --build_dir ${HiTLS_BUILD_DIR})
|
||||
|
||||
include(${HiTLS_BUILD_DIR}/modules.cmake)
|
||||
@@ -0,0 +1,125 @@
|
||||
木兰宽松许可证, 第2版
|
||||
|
||||
木兰宽松许可证, 第2版
|
||||
2020年1月 http://license.coscl.org.cn/MulanPSL2
|
||||
|
||||
您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束:
|
||||
|
||||
0. 定义
|
||||
|
||||
“软件” 是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。
|
||||
|
||||
“贡献” 是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。
|
||||
|
||||
“贡献者” 是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。
|
||||
|
||||
“法人实体” 是指提交贡献的机构及其“关联实体”。
|
||||
|
||||
“关联实体” 是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。
|
||||
|
||||
1. 授予版权许可
|
||||
|
||||
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。
|
||||
|
||||
2. 授予专利许可
|
||||
|
||||
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。
|
||||
|
||||
3. 无商标许可
|
||||
|
||||
“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。
|
||||
|
||||
4. 分发限制
|
||||
|
||||
您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。
|
||||
|
||||
5. 免责声明与责任限制
|
||||
|
||||
“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。
|
||||
|
||||
6. 语言
|
||||
|
||||
“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。
|
||||
|
||||
条款结束
|
||||
|
||||
如何将木兰宽松许可证,第2版,应用到您的软件
|
||||
|
||||
如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步:
|
||||
|
||||
1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字;
|
||||
|
||||
2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中;
|
||||
|
||||
3, 请将如下声明文本放入每个源文件的头部注释中。
|
||||
|
||||
Copyright (c) [Year] [name of copyright holder]
|
||||
[Software Name] is licensed under Mulan PSL v2.
|
||||
You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
You may obtain a copy of Mulan PSL v2 at:
|
||||
http://license.coscl.org.cn/MulanPSL2
|
||||
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
See the Mulan PSL v2 for more details.
|
||||
Mulan Permissive Software License,Version 2
|
||||
Mulan Permissive Software License,Version 2 (Mulan PSL v2)
|
||||
|
||||
January 2020 http://license.coscl.org.cn/MulanPSL2
|
||||
|
||||
Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions:
|
||||
|
||||
0. Definition
|
||||
|
||||
Software means the program and related documents which are licensed under this License and comprise all Contribution(s).
|
||||
|
||||
Contribution means the copyrightable work licensed by a particular Contributor under this License.
|
||||
|
||||
Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License.
|
||||
|
||||
Legal Entity means the entity making a Contribution and all its Affiliates.
|
||||
|
||||
Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.
|
||||
|
||||
1. Grant of Copyright License
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.
|
||||
|
||||
2. Grant of Patent License
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken.
|
||||
|
||||
3. No Trademark License
|
||||
|
||||
No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in section 4.
|
||||
|
||||
4. Distribution Restriction
|
||||
|
||||
You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software.
|
||||
|
||||
5. Disclaimer of Warranty and Limitation of Liability
|
||||
|
||||
THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
6. Language
|
||||
|
||||
THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL.
|
||||
|
||||
END OF THE TERMS AND CONDITIONS
|
||||
|
||||
How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software
|
||||
|
||||
To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps:
|
||||
|
||||
Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;
|
||||
Create a file named "LICENSE" which contains the whole context of this License in the first directory of your software package;
|
||||
Attach the statement to the appropriate annotated syntax at the beginning of each source file.
|
||||
Copyright (c) [Year] [name of copyright holder]
|
||||
[Software Name] is licensed under Mulan PSL v2.
|
||||
You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
You may obtain a copy of Mulan PSL v2 at:
|
||||
http://license.coscl.org.cn/MulanPSL2
|
||||
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
See the Mulan PSL v2 for more details.
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
[English](./README.md) | 简体中文
|
||||
|
||||
# openHiTLS
|
||||
欢迎访问openHiTLS代码仓,该代码仓的项目官网是openHiTLS社区<https://openhitls.net>,openHiTLS的目标是提供高效、敏捷的全场景开源密码学开发套件。openHiTLS已支持通用的标准密码算法、(D)TLS、TLCP等安全通信协议,更多特性待规划。
|
||||
|
||||
## 概述
|
||||
|
||||
openHiTLS架构高度模块化,可通过模块和特性配置。RAM/ROM尺寸取决于所选的特性。openHiTLS为密码算法提供最佳性能优化。当前已支持4个组件和算法特性可按需配置,支持ARM、x86架构CPU上的算法性能优化,更多架构和特性待规划。
|
||||
|
||||
## 特性简介
|
||||
|
||||
1. 功能特性:TLS1.2、TLS1.3、DTLS1.2、TLCP;AES,SM4,Chacha20,RSA,DSA,ECDSA,ECDH,DH,SM2,DRBG,HKDF,SCRYPT,PBKDF2,SHA2,SHA3,MD5,SM3,HMAC;X509
|
||||
2. DFX特性:高度模块化特性按需配置的敏捷架构,ARM、x86上的算法性能优化,日志和错误堆栈功能的可维可测性
|
||||
|
||||
## 组件简介
|
||||
|
||||
目前,openHiTLS有4个组件,其中BSL组件需和其他组件一起使用。
|
||||
- BSL是Base Support Layer的缩写,提供基础C类标准的增强功能和OS适配器,需与其他模块一起使用
|
||||
- 密码算法组件(Crypto)提供了完整的密码功能,且性能较优。该组件既可以被TLS使用,也可与BSL一起使用
|
||||
- TLS是Transport Layer Security的缩写,涵盖了TLS1.3及之前的TLS版本,会与Crypto、BSL以及其他三方密码组件或PKI库一起使用
|
||||
- X509组件当前提供了能够支撑TLS协议建链的基础功能,后续逐步完善功能
|
||||
|
||||
|
||||
## 开发
|
||||
|
||||
### 依赖准备
|
||||
|
||||
openHiTLS依赖于Secure C,因此需将Secure C下载到${openHiTLS_dir}/platform/Secure_C,Secure C的一个官方Git库是 <https://gitee.com/openeuler/libboundscheck>。
|
||||
|
||||
* 下载安全函数库
|
||||
```bash
|
||||
# 方式1 与openHiTLS代码仓一起拉取
|
||||
git clone --recurse-submodules https://gitcode.com/openhitls/openhitls.git
|
||||
|
||||
# 方式2 单独拉取安全函数库
|
||||
git clone https://gitcode.com/openhitls/openhitls.git
|
||||
cd ${openHiTLS_dir}
|
||||
git clone https://gitee.com/openeuler/libboundscheck platform/Secure_C
|
||||
```
|
||||
|
||||
* 构建安全函数库
|
||||
```bash
|
||||
cd ${openHiTLS_dir}/platform/Secure_C
|
||||
make -j
|
||||
```
|
||||
|
||||
### 致应用开发人员
|
||||
|
||||
正式版本的源码镜像尚未正式开放、还在规划当中。
|
||||
|
||||
|
||||
官方代码仓库托管在<https://gitcode.com/openhitls>,您可以通过如下命令将Git库克隆为一个本地副本进行使用:
|
||||
```
|
||||
git clone https://gitcode.com/openhitls/openhitls.git
|
||||
```
|
||||
如果您有意贡献代码,请在gitcode上复制openhitls库,再克隆您的公共副本:
|
||||
```
|
||||
git clone https://gitcode.com/"your gitcode name"/openhitls.git
|
||||
```
|
||||
|
||||
## 文档
|
||||
|
||||
本文档旨在帮助开发者和贡献者更快地上手openHiTLS,详情参考[文档列表](docs/index/index.md) 。
|
||||
|
||||
## 构建与安装
|
||||
|
||||
在Linux系统中进行构建与安装时,可参考[构建安装指导](docs/zh/4_使用指南/1_构建及安装指导.md)
|
||||
Linux系统中的主要步骤有:
|
||||
|
||||
1. 准备构建目录:
|
||||
```
|
||||
cd openHiTLS && mkdir -p ./build && cd ./build
|
||||
```
|
||||
2. 生成构建配置:
|
||||
```
|
||||
python3 ../configure.py ["option"]
|
||||
```
|
||||
* C全量构建
|
||||
```
|
||||
python3 ../configure.py --enable hitls_bsl hitls_crypto hitls_tls hitls_x509 --lib_type static --bits=64 --system=linux
|
||||
```
|
||||
|
||||
* x8664优化全量构建:
|
||||
```
|
||||
python3 ../configure.py --enable hitls_bsl hitls_crypto hitls_tls hitls_x509 --lib_type static --bits=64 --system=linux --asm_type x8664
|
||||
```
|
||||
选项介绍可参考[构建安装指导](docs/zh/4_使用指南/1_构建及安装指导.md)
|
||||
|
||||
3. 生成构建脚本:
|
||||
```
|
||||
cmake ..
|
||||
```
|
||||
4. 执行构建和安装:
|
||||
```
|
||||
make && make install
|
||||
```
|
||||
|
||||
## 贡献
|
||||
|
||||
如果您有意为openHiTLS社区做贡献,请先在[CLA签署](https://cla.openhitls.net)平台上完成CLA签署。
|
||||
@@ -0,0 +1,99 @@
|
||||
[简体中文](./README-zh.md) | English
|
||||
|
||||
# openHiTLS
|
||||
Welcome to visit the openHiTLS Code Repository, which is under the openHiTLS community: <https://openhitls.net>. openHiTLS aims to provide highly efficient and agile open-source SDKs for Cryptography and Transport Layer Security in all scenarios. openHiTLS is developing and supports some common standard cryptographic algorithms, (D)TLS, TLCP protocols currently. More features are to be planned.
|
||||
|
||||
## Overview
|
||||
|
||||
The architecture of openHiTLS is highly modular, and openHiTLS can be configured in modules and features. The RAM/ROM footprint depends on the features selected. It provides the optimal performance optimization for cryptographic algorithms. Currently, 4 components and cryptographic algorithms are configured, and the performance optimization of ShangMi cryptographic algorithms on ARM, x86 is ready. More architectures and features are to be planned.
|
||||
|
||||
## Feature Introduction
|
||||
|
||||
1. Functional feature: TLS1.2, TLS1.3, DTLS1.2. TLCP; AES, SM4, Chacha20, RSA, ECDSA, ECDH, SM2, DRBG, HKDF, SCRYPT, PBKDF2, SHA2, SHA3, MD5, SM3, HMAC; X509
|
||||
2. DFX feature: highly modular with features configured, performance optimization on ARM, x86 maintainability and testability with logs and error stacks.
|
||||
|
||||
## Component Introduction
|
||||
|
||||
openHiTLS include 4 components currently. The BSL component will be used with other components.
|
||||
- The bsl is short for Base Support Layer, which provides the base C standand enhanced functions and OS adapter. It will be used with other modules
|
||||
- The crypto is short for cryptographic algorithms, which provides the full cryptographic functions with high performance. It will be used by tls, and can also be used with bsl
|
||||
- The tls is short for Transport Layer Security, which provides all tls protocol versions up to tls1.3. It will be used with crypto and bsl or other third-party crypto and pki libraries
|
||||
- The X509 component currently provides basic functions that can support TLS to work, and will gradually improve the functions in the future
|
||||
|
||||
## Development
|
||||
|
||||
### Dependency Preparation
|
||||
|
||||
openHiTLS depends on Secure C which should be downloaded to ${openHiTLS_dir}/platform/Secure_C. One of the official git repositories of Secure C is located at <https://gitee.com/openeuler/libboundscheck>.
|
||||
|
||||
* Download the security library
|
||||
|
||||
```bash
|
||||
# Method 1: Pull it with the openHiTLS code repository
|
||||
git clone --recurse-submodules https://gitcode.com/openhitls/openhitls.git
|
||||
|
||||
# Method 2: Pull the security library separately
|
||||
git clone https://gitcode.com/openhitls/openhitls.git
|
||||
cd ${openHiTLS_dir}
|
||||
git clone https://gitee.com/openeuler/libboundscheck platform/Secure_C
|
||||
```
|
||||
|
||||
* Build security library
|
||||
```bash
|
||||
cd ${openHiTLS_dir}/platform/Secure_C
|
||||
make -j
|
||||
```
|
||||
|
||||
### For Application Developers
|
||||
|
||||
Source code mirroring of the official releases is pending for planning.
|
||||
|
||||
|
||||
The official source code repository is located at <https://gitcode.com/openhitls>. A local copy of the git repository can be obtained by cloning it using:
|
||||
```
|
||||
git clone https://gitcode.com/openhitls/openhitls.git
|
||||
```
|
||||
If you are going to contribute, you need to fork the openhitls repository on gitee and clone your public fork instead:
|
||||
```
|
||||
git clone https://gitcode.com/"your gitcode name"/openhitls.git
|
||||
```
|
||||
|
||||
## Document
|
||||
This document is designed to improve the learning efficiency of developers and contributors on openHiTLS. Refer to the [docs](docs/index/index.md).
|
||||
|
||||
## Build and Installation
|
||||
The major steps in Linux are as follows. Refer to [build & install](docs/en/4_User%20Guide/1_Build%20and%20Installation%20Guide.md)
|
||||
The major steps in Linux:
|
||||
|
||||
Step 1 (Prepare the build directory):
|
||||
```
|
||||
cd openHiTLS && mkdir -p ./build && cd ./build
|
||||
```
|
||||
Step 2 (Generate configurations):
|
||||
```
|
||||
python3 ../configure.py ["option"]
|
||||
```
|
||||
|
||||
* C Full build:
|
||||
```
|
||||
python3 ../configure.py --enable hitls_bsl hitls_crypto hitls_tls hitls_x509 --lib_type static --bits=64 --system=linux
|
||||
```
|
||||
|
||||
* x8664 Optimize the full build:
|
||||
```
|
||||
python3 ../configure.py --enable hitls_bsl hitls_crypto hitls_tls hitls_x509 --lib_type static --bits=64 --system=linux --asm_type x8664
|
||||
```
|
||||
The options are described in [Build Installation Guide](docs/en/4_User%20Guide/1_Build%20and%20Installation%20Guide.md)
|
||||
|
||||
Step 3 (Generate the build script):
|
||||
```
|
||||
cmake ..
|
||||
```
|
||||
Step 4 (Build and install):
|
||||
```
|
||||
make && make install
|
||||
```
|
||||
|
||||
## Contribution
|
||||
|
||||
If you plan to contribute to the openHiTLS community, please visit the link [CLA Signing](https://cla.openhitls.net) to complete CLA signing.
|
||||
@@ -0,0 +1,819 @@
|
||||
THIRD PARTY OPEN SOURCE SOFTWARE NOTICE
|
||||
|
||||
Please note we provide an open source software notice for the third party open source software along with this software and/or this software component contributed by Huawei (in the following just “this SOFTWARE”). The open source software licenses are granted by the respective right holders.
|
||||
|
||||
Warranty Disclaimer
|
||||
|
||||
The open source software in this software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the applicable licenses for more details.
|
||||
|
||||
Copyright Notice and License Texts
|
||||
|
||||
Software: lksctp-tools v1.0.19
|
||||
|
||||
Copyright notice:
|
||||
|
||||
(C) Copyright 2007 Hewlett-Packard Development Company, L.P.
|
||||
(C) Copyright IBM Corp. 2001, 2003
|
||||
Copyright 2001 Motorola, Cisco, Intel, Nokia, La Monte Yarroll.
|
||||
Copyright 2002 Nokia, La Monte Yarroll, Intel.
|
||||
|
||||
License:LGPL-2.1 license; GPL-2.0 license
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef BSL_ASN1_H
|
||||
#define BSL_ASN1_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "bsl_list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BSL_ASN1_CLASS_UNIVERSAL 0x0 /* bit8 0, bit7 0 */
|
||||
#define BSL_ASN1_CLASS_APPLICATION 0x40 /* bit8 0, bit7 1 */
|
||||
#define BSL_ASN1_CLASS_CTX_SPECIFIC 0x80 /* bit8 1, bit7 0 */
|
||||
#define BSL_ASN1_CLASS_PRIVATE 0xC0 /* bit8 1, bit7 1 */
|
||||
|
||||
#define BSL_ASN1_TAG_CONSTRUCTED 0x20
|
||||
|
||||
/* ASN1 tag from x.680 */
|
||||
#define BSL_ASN1_TAG_BOOLEAN 0x01
|
||||
#define BSL_ASN1_TAG_INTEGER 0x02
|
||||
#define BSL_ASN1_TAG_BITSTRING 0x03
|
||||
#define BSL_ASN1_TAG_OCTETSTRING 0x04
|
||||
#define BSL_ASN1_TAG_NULL 0x05
|
||||
#define BSL_ASN1_TAG_OBJECT_ID 0x06
|
||||
#define BSL_ASN1_TAG_OBJECT_DESCP 0x07
|
||||
#define BSL_ASN1_TAG_INSTANCE_OF 0x08
|
||||
#define BSL_ASN1_TAG_REAL 0x09
|
||||
#define BSL_ASN1_TAG_ENUMERATED 0x0A
|
||||
#define BSL_ASN1_TAG_EMBEDDED_PDV 0x0B
|
||||
#define BSL_ASN1_TAG_UTF8STRING 0x0C
|
||||
#define BSL_ASN1_TAG_RALATIVE_ID 0x0D
|
||||
#define BSL_ASN1_TAG_TIME 0x0E
|
||||
#define BSL_ASN1_TAG_SEQUENCE 0x10
|
||||
#define BSL_ASN1_TAG_SET 0x11
|
||||
#define BSL_ASN1_TAG_PRINTABLESTRING 0x13
|
||||
#define BSL_ASN1_TAG_IA5STRING 0x16
|
||||
|
||||
#define BSL_ASN1_TAG_UTCTIME 0x17
|
||||
#define BSL_ASN1_TAG_GENERALIZEDTIME 0x18
|
||||
#define BSL_ASN1_TAG_BMPSTRING 0x1E
|
||||
|
||||
/* Custom types, use private class to prevent conflicts */
|
||||
#define BSL_ASN1_TAG_CHOICE (BSL_ASN1_CLASS_PRIVATE | 1)
|
||||
#define BSL_ASN1_TAG_ANY (BSL_ASN1_CLASS_PRIVATE | 2)
|
||||
|
||||
/* The current value is flags, is used to guide asn1 encoding or decoding */
|
||||
#define BSL_ASN1_FLAG_OPTIONAL 1
|
||||
/* The current value is default, is used to guide asn1 encoding or decoding */
|
||||
#define BSL_ASN1_FLAG_DEFAULT 2
|
||||
/* Only parsing or encoding headers, and child nodes are not traversed */
|
||||
#define BSL_ASN1_FLAG_HEADERONLY 4
|
||||
/* The implied values are of the same type */
|
||||
#define BSL_ASN1_FLAG_SAME 8
|
||||
|
||||
#define BSL_ASN1_MAX_TEMPLATE_DEPTH 6
|
||||
|
||||
#define BSL_ASN1_UTCTIME_LEN 13 // YYMMDDHHMMSSZ
|
||||
#define BSL_ASN1_GENERALIZEDTIME_LEN 15 // YYYYMMDDHHMMSSZ
|
||||
|
||||
#define BSL_ASN1_List BslList
|
||||
|
||||
typedef enum {
|
||||
BSL_ASN1_TYPE_GET_ANY_TAG = 0,
|
||||
BSL_ASN1_TYPE_CHECK_CHOICE_TAG = 1
|
||||
} BSL_ASN1_CALLBACK_TYPE;
|
||||
|
||||
typedef struct _BSL_ASN1_TemplateItem {
|
||||
/* exptect tag */
|
||||
uint8_t tag;
|
||||
/* corresponding to the tag flag */
|
||||
uint8_t flags:5;
|
||||
uint8_t depth:3;
|
||||
} BSL_ASN1_TemplateItem;
|
||||
|
||||
typedef struct _BSL_ASN1_Template {
|
||||
BSL_ASN1_TemplateItem *templItems;
|
||||
uint32_t templNum;
|
||||
} BSL_ASN1_Template;
|
||||
|
||||
typedef struct _BSL_ASN1_Buffer {
|
||||
uint8_t tag;
|
||||
uint32_t len;
|
||||
uint8_t *buff;
|
||||
} BSL_ASN1_Buffer;
|
||||
|
||||
typedef struct _BSL_ASN1_BitString {
|
||||
uint8_t *buff;
|
||||
uint32_t len;
|
||||
uint8_t unusedBits;
|
||||
} BSL_ASN1_BitString;
|
||||
|
||||
/**
|
||||
* @ingroup bsl_asn1
|
||||
* @brief The extension function for template decoding is used to handle decoding of uncertain data types.
|
||||
*
|
||||
* @param type [IN] BSL_ASN1_CALLBACK_TYPE
|
||||
* @param idx [IN] The position of the data to be processed in the template.
|
||||
* @param data [IN] The data to be processed.
|
||||
* @param expVal [OUT] Output value.
|
||||
*/
|
||||
typedef int32_t(*BSL_ASN1_DecTemplCallBack) (int32_t type, int32_t idx, void *data, void *expVal);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_asn1
|
||||
* @brief The extension function for template decoding is used to convert an ASN item into a list.
|
||||
*
|
||||
* @param layer [IN] The layer of a list, used to construct the name node will use.
|
||||
* @param asn [IN] The asn1 item to be decoded.
|
||||
* @param cbParam [IN/OUT] The other parameters for decoding.
|
||||
* @param list [OUT] Output value.
|
||||
*/
|
||||
typedef int32_t(*BSL_ASN1_ParseListAsnItem)(uint32_t layer, BSL_ASN1_Buffer *asn, void *cbParam, BSL_ASN1_List *list);
|
||||
|
||||
typedef struct _BSL_ASN1_DecodeListParam {
|
||||
uint32_t layer;
|
||||
uint8_t *expTag;
|
||||
} BSL_ASN1_DecodeListParam;
|
||||
|
||||
/**
|
||||
* @ingroup bsl_asn1
|
||||
* @brief Obtain the length of V or LV in an ASN1 TLV structure.
|
||||
*
|
||||
* @param encode [IN/OUT] Data to be decoded. Update the offset after decoding.
|
||||
* @param encLen [IN/OUT] The length of the data to be decoded.
|
||||
* @param completeLen [IN] True: Get the length of L+V; False: Get the length of V.
|
||||
* @param len [OUT] Output.
|
||||
* @retval BSL_SUCCESS, success.
|
||||
* Other error codes see the bsl_errno.h.
|
||||
*/
|
||||
int32_t BSL_ASN1_DecodeLen(uint8_t **encode, uint32_t *encLen, bool completeLen, uint32_t *len);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_asn1
|
||||
* @brief Obtain the length of V in an ASN1 TLV structure based on the tag.
|
||||
*
|
||||
* @param tag [IN] ASN1 tag.
|
||||
* @param encode [IN/OUT] Data to be decoded. Update the offset after decoding.
|
||||
* @param encLen [IN/OUT] The length of the data to be decoded.
|
||||
* @param valLen [OUT] The length of V.
|
||||
* @retval BSL_SUCCESS, success.
|
||||
* Other error codes see the bsl_errno.h.
|
||||
*/
|
||||
int32_t BSL_ASN1_DecodeTagLen(uint8_t tag, uint8_t **encode, uint32_t *encLen, uint32_t *valLen);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_asn1
|
||||
* @brief Decoding data of type 'SEQUENCE OF' or 'SET OF'.
|
||||
*
|
||||
* @param param [IN] The parameters of the data to be decoded.
|
||||
* @param asn [IN] The data to be decoded.
|
||||
* @param parseListItemCb [IN] User defined callback function used to convert an ASN item into a list.
|
||||
* @param cbParam [IN/OUT] The parameters in the callback function.
|
||||
* @param list [OUT] Decoding result.
|
||||
* @retval BSL_SUCCESS, success.
|
||||
* Other error codes see the bsl_errno.h.
|
||||
*/
|
||||
int32_t BSL_ASN1_DecodeListItem(BSL_ASN1_DecodeListParam *param, BSL_ASN1_Buffer *asn,
|
||||
BSL_ASN1_ParseListAsnItem parseListItemCb, void *cbParam, BSL_ASN1_List *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_asn1
|
||||
* @brief Decoding of primitive type data.
|
||||
*
|
||||
* @param asn [IN] The data to be decoded.
|
||||
* @param decodeData [OUT] Decoding result.
|
||||
* @retval BSL_SUCCESS, success.
|
||||
* Other error codes see the bsl_errno.h.
|
||||
*/
|
||||
int32_t BSL_ASN1_DecodePrimitiveItem(BSL_ASN1_Buffer *asn, void *decodeData);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_asn1
|
||||
* @brief Template decoding method.
|
||||
*
|
||||
* @param templ [IN] Encoding template.
|
||||
* @param decTemlCb [IN] Function for handling uncertain types of data.
|
||||
* @param encode [IN/OUT] Data to be decoded. Update the offset after decoding.
|
||||
* @param encLen [IN/OUT] The length of the data to be decoded.
|
||||
* @param asnArr [OUT] List of data to be decoded.
|
||||
* @param arrNum [IN] The number of data to be encoded, which is determined by the template.
|
||||
* @retval BSL_SUCCESS, success.
|
||||
* Other error codes see the bsl_errno.h.
|
||||
*/
|
||||
int32_t BSL_ASN1_DecodeTemplate(BSL_ASN1_Template *templ, BSL_ASN1_DecTemplCallBack decTemlCb,
|
||||
uint8_t **encode, uint32_t *encLen, BSL_ASN1_Buffer *asnArr, uint32_t arrNum);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_asn1
|
||||
* @brief Decode one asn1 item.
|
||||
*
|
||||
* @param encode [IN/OUT] Data to be decoded. Update the offset after decoding.
|
||||
* @param encLen [IN/OUT] The length of the data to be decoded.
|
||||
* @param asnItem [OUT] Output.
|
||||
* @retval BSL_SUCCESS, success.
|
||||
* Other error codes see the bsl_errno.h.
|
||||
*/
|
||||
int32_t BSL_ASN1_DecodeItem(uint8_t **encode, uint32_t *encLen, BSL_ASN1_Buffer *asnItem);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_asn1
|
||||
* @brief Obtain the length of an ASN1 TLV structure.
|
||||
*
|
||||
* @param data [IN] Data to be decoded. Update the offset after decoding.
|
||||
* @param dataLen [OUT] Decoding result.
|
||||
* @retval BSL_SUCCESS, success.
|
||||
* Other error codes see the bsl_errno.h.
|
||||
*/
|
||||
int32_t BSL_ASN1_GetCompleteLen(uint8_t *data, uint32_t *dataLen);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_asn1
|
||||
* @brief Template encoding method.
|
||||
*
|
||||
* @attention
|
||||
* 1. For SET types: The elements in the template should be sorted into tag order.
|
||||
* 2. The type for the following types of BSL_ASN1_Buffer.buff are as follows:
|
||||
* a. BSL_ASN1_TAG_BOOLEAN: bool *
|
||||
* b. BSL_ASN1_TAG_BITSTRING: BSL_ASN1_BitString *
|
||||
* c. BSL_ASN1_TAG_UTCTIME|BSL_ASN1_TAG_GENERALIZEDTIME: BSL_TIME *
|
||||
*
|
||||
* @param templ [IN] Encoding template.
|
||||
* @param asnArr [IN] List of data to be encoded.
|
||||
* @param arrNum [IN] The number of data to be encoded, which is determined by the template.
|
||||
* @param encode [OUT] Encoding result.
|
||||
* @param encLen [OUT] Encoding length.
|
||||
* @retval BSL_SUCCESS, success.
|
||||
* Other error codes see the bsl_errno.h.
|
||||
*/
|
||||
int32_t BSL_ASN1_EncodeTemplate(BSL_ASN1_Template *templ, BSL_ASN1_Buffer *asnArr, uint32_t arrNum,
|
||||
uint8_t **encode, uint32_t *encLen);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_asn1
|
||||
* @brief Encoding data of type 'SEQUENCE OF' or 'SET OF'.
|
||||
*
|
||||
* @attention
|
||||
* 1. BSL_ASN1_TAG_SEQUENCE is type 'SEQUENCE OF'.
|
||||
* 2. BSL_ASN1_TAG_SET is type 'SET OF'.
|
||||
* 3. The sorting in 'SET OF' is currently not supported.
|
||||
*
|
||||
* @param tag [IN] BSL_ASN1_TAG_SEQUENCE or BSL_ASN1_TAG_SET
|
||||
* @param listSize [IN] The number of elements in the list.
|
||||
* @param templ [IN] Template for elements in the list.
|
||||
* @param asnArr [IN] List of data to be encoded.
|
||||
* @param arrNum [IN] The number of data to be encoded.
|
||||
* @param out [OUT] Encoding result.
|
||||
* @retval BSL_SUCCESS, success.
|
||||
* Other error codes see the bsl_errno.h.
|
||||
*/
|
||||
int32_t BSL_ASN1_EncodeListItem(uint8_t tag, uint32_t listSize, BSL_ASN1_Template *templ, BSL_ASN1_Buffer *asnArr,
|
||||
uint32_t arrNum, BSL_ASN1_Buffer *out);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_asn1
|
||||
* @brief Encode the smaller positive integer.
|
||||
*
|
||||
* @param tag [IN] BSL_ASN1_TAG_INTEGER or BSL_ASN1_TAG_ENUMERATED
|
||||
* @param limb [IN] Positive integer.
|
||||
* @param asn [OUT] Encoding result.
|
||||
* @retval BSL_SUCCESS, success.
|
||||
* Other error codes see the bsl_errno.h.
|
||||
*/
|
||||
int32_t BSL_ASN1_EncodeLimb(uint8_t tag, uint64_t limb, BSL_ASN1_Buffer *asn);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BSL_ASN1_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef BSL_ASN1_LOCAL_H
|
||||
#define BSL_ASN1_LOCAL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "bsl_asn1.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BSL_ASN1_VAL_MAX_BIT_STRING_LEN 7
|
||||
#define BSL_ASN1_MAX_LIST_NEST_EPTH 2
|
||||
#define BSL_ASN1_FLAG_OPTIONAL_DEFAUL (BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_DEFAULT)
|
||||
|
||||
/* Gets the mask of the class */
|
||||
#define BSL_ASN1_CLASS_MASK 0xC0
|
||||
|
||||
typedef struct _ASN1_AnyOrChoiceParam {
|
||||
int32_t idx;
|
||||
void *previousAsnOrTag;
|
||||
BSL_ASN1_DecTemplCallBack tagCb;
|
||||
} BSL_ASN1_AnyOrChoiceParam;
|
||||
|
||||
typedef struct _BSL_ASN1_EncodeItem {
|
||||
uint64_t asnOctetNum; // tag + len + content
|
||||
BSL_ASN1_Buffer *asn;
|
||||
uint8_t tag;
|
||||
uint8_t depth;
|
||||
uint8_t skip; // Whether to skip processing template item
|
||||
uint8_t optional;
|
||||
uint8_t lenOctetNum; // The maximum number of the length octets is 126 + 1
|
||||
} BSL_ASN1_EncodeItem;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BSL_ASN1_LOCAL_H
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef BSL_BASE64_INTERNAL_H
|
||||
#define BSL_BASE64_INTERNAL_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_BASE64
|
||||
|
||||
#include "bsl_base64.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct BASE64_ControlBlock {
|
||||
/* size of the unencoded block in the current buffer */
|
||||
uint32_t num;
|
||||
/*
|
||||
* Size of the block for internal encoding and decoding.
|
||||
* The size of the coding block is set to 48, and the size of the decoding block is set to 64.
|
||||
*/
|
||||
uint32_t length;
|
||||
/* see BSL_BASE64_FLAGS*, for example: BSL_BASE64_FLAGS_NO_NEWLINE, means process without '\n' */
|
||||
uint32_t flags;
|
||||
uint32_t paddingCnt;
|
||||
/* codec buffer */
|
||||
uint8_t buf[HITLS_BASE64_CTX_BUF_LENGTH];
|
||||
};
|
||||
|
||||
#define BASE64_ENCODE_BYTES 3 // encode 3 bytes at a time
|
||||
#define BASE64_DECODE_BYTES 4 // decode 4 bytes at a time
|
||||
#define BASE64_BLOCK_SIZE 1024
|
||||
#define BASE64_PAD_MAX 2
|
||||
#define BASE64_DECODE_BLOCKSIZE 64
|
||||
#define BASE64_CTX_BUF_SIZE HITLS_BASE64_ENCODE_LENGTH(BASE64_BLOCK_SIZE) + 10
|
||||
#define BSL_BASE64_ENC_ENOUGH_LEN(len) (((len) + 2) / 3 * 4 + 1)
|
||||
#define BSL_BASE64_DEC_ENOUGH_LEN(len) (((len) + 3) / 4 * 3)
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base64
|
||||
* @brief Obtain the remaining context buf and determine whether to invoke final().
|
||||
* @par Description: Obtains the remaining length "num" of the context buf.
|
||||
* @param ctx [IN] Input context.
|
||||
* @param num [OUT] Obtain the remaining length of the buf.
|
||||
* @retval If it is success, BSL_SUCCESS is returned. Otherwise, a failure error code is returned.
|
||||
*/
|
||||
int32_t BSL_Base64GetNum(BSL_Base64Ctx *ctx, uint32_t *num);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* HITLS_BSL_BASE64 */
|
||||
#endif /* conditional include */
|
||||
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_BASE64
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "securec.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_err_internal.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_base64_internal.h"
|
||||
#include "bsl_base64.h"
|
||||
|
||||
/* BASE64 mapping table */
|
||||
static const uint8_t BASE64_DECODE_MAP_TABLE[] = {
|
||||
67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 64U, 67U, 67U, 64U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U,
|
||||
67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 64U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 62U, 67U, 66U,
|
||||
67U, 63U, 52U, 53U, 54U, 55U, 56U, 57U, 58U, 59U, 60U, 61U, 67U, 67U, 67U, 65U, 67U, 67U, 67U, 0U, 1U, 2U, 3U,
|
||||
4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 16U, 17U, 18U, 19U, 20U, 21U, 22U, 23U, 24U, 25U, 67U,
|
||||
67U, 67U, 67U, 67U, 67U, 26U, 27U, 28U, 29U, 30U, 31U, 32U, 33U, 34U, 35U, 36U, 37U, 38U, 39U, 40U, 41U, 42U, 43U,
|
||||
44U, 45U, 46U, 47U, 48U, 49U, 50U, 51U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U,
|
||||
67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U,
|
||||
67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U,
|
||||
67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U,
|
||||
67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U,
|
||||
67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U, 67U,
|
||||
67U, 67U, 67U};
|
||||
|
||||
|
||||
BSL_Base64Ctx *BSL_BASE64_CtxNew(void)
|
||||
{
|
||||
return BSL_SAL_Malloc(sizeof(BSL_Base64Ctx));
|
||||
}
|
||||
|
||||
void BSL_BASE64_CtxFree(BSL_Base64Ctx *ctx)
|
||||
{
|
||||
BSL_SAL_FREE(ctx);
|
||||
}
|
||||
|
||||
void BSL_BASE64_CtxClear(BSL_Base64Ctx *ctx)
|
||||
{
|
||||
BSL_SAL_CleanseData(ctx, (uint32_t)sizeof(BSL_Base64Ctx));
|
||||
}
|
||||
|
||||
static int32_t BslBase64EncodeParamsValidate(const uint8_t *srcBuf, const uint32_t srcBufLen,
|
||||
const char *dstBuf, uint32_t *dstBufLen)
|
||||
{
|
||||
if (srcBuf == NULL || srcBufLen == 0U || dstBuf == NULL || dstBufLen == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
/* The length of dstBuf of the user must be at least (srcBufLen+2)/3*4+1 */
|
||||
if (*dstBufLen < BSL_BASE64_ENC_ENOUGH_LEN(srcBufLen)) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_BASE64_BUF_NOT_ENOUGH);
|
||||
return BSL_BASE64_BUF_NOT_ENOUGH;
|
||||
}
|
||||
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static void BslBase64ArithEncodeProc(const uint8_t *srcBuf, const uint32_t srcBufLen,
|
||||
char *dstBuf, uint32_t *dstBufLen)
|
||||
{
|
||||
/* base64-encoding mapping table */
|
||||
static const char *base64Letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
uint32_t dstIdx = 0U;
|
||||
const uint8_t *tmpBuf = srcBuf;
|
||||
uint32_t tmpLen;
|
||||
|
||||
/* @alias Encode characters based on the BASE64 encoding rule. */
|
||||
for (tmpLen = srcBufLen; tmpLen > 2U; tmpLen -= 3U) {
|
||||
dstBuf[dstIdx] = base64Letter[(tmpBuf[0] >> 2U) & 0x3FU];
|
||||
dstIdx++;
|
||||
dstBuf[dstIdx] = base64Letter[((tmpBuf[0] & 0x3U) << 4U) | ((tmpBuf[1U] & 0xF0U) >> 4U)];
|
||||
dstIdx++;
|
||||
dstBuf[dstIdx] = base64Letter[((tmpBuf[1U] & 0x0FU) << 2U) | ((tmpBuf[2U] & 0xC0U) >> 6U)];
|
||||
dstIdx++;
|
||||
dstBuf[dstIdx] = base64Letter[tmpBuf[2U] & 0x3FU];
|
||||
dstIdx++;
|
||||
tmpBuf = &tmpBuf[3U];
|
||||
}
|
||||
|
||||
/* Handle the case where the remaining length is not 0. */
|
||||
if (tmpLen > 0U) {
|
||||
/* Padded the first byte. */
|
||||
dstBuf[dstIdx] = base64Letter[(tmpBuf[0] >> 2U) & 0x3FU];
|
||||
dstIdx++;
|
||||
if (tmpLen == 1U) {
|
||||
/* Process the case where the remaining length is 1. */
|
||||
dstBuf[dstIdx] = base64Letter[((tmpBuf[0U] & 0x3U) << 4U)];
|
||||
dstIdx++;
|
||||
dstBuf[dstIdx] = '=';
|
||||
dstIdx++;
|
||||
} else {
|
||||
/* Process the case where the remaining length is 2. */
|
||||
dstBuf[dstIdx] = base64Letter[((tmpBuf[0U] & 0x3U) << 4U) | ((tmpBuf[1U] & 0xF0U) >> 4U)];
|
||||
dstIdx++;
|
||||
dstBuf[dstIdx] = base64Letter[((tmpBuf[1U] & 0x0Fu) << 2U)];
|
||||
dstIdx++;
|
||||
}
|
||||
/* Fill the last '='. */
|
||||
dstBuf[dstIdx++] = '=';
|
||||
}
|
||||
/* Fill terminator. */
|
||||
dstBuf[dstIdx] = '\0';
|
||||
*dstBufLen = dstIdx;
|
||||
}
|
||||
|
||||
/* Encode the entire ctx->buf, 48 characters in total, and return the number of decoded characters. */
|
||||
static void BslBase64EncodeBlock(BSL_Base64Ctx *ctx, const uint8_t **srcBuf, uint32_t *srcBufLen,
|
||||
char **dstBuf, uint32_t *dstBufLen, uint32_t remainLen)
|
||||
{
|
||||
uint32_t tmpOutLen = 0;
|
||||
uint32_t offset = 0;
|
||||
|
||||
BslBase64ArithEncodeProc(*srcBuf, ctx->length, *dstBuf, &tmpOutLen);
|
||||
|
||||
ctx->num = 0;
|
||||
|
||||
offset = ((remainLen == 0) ? (ctx->length) : remainLen);
|
||||
*srcBuf += offset;
|
||||
*srcBufLen -= offset;
|
||||
*dstBufLen += tmpOutLen;
|
||||
*dstBuf += tmpOutLen;
|
||||
|
||||
if ((ctx->flags & BSL_BASE64_FLAGS_NO_NEWLINE) == 0) {
|
||||
*(*dstBuf) = '\n';
|
||||
(*dstBuf)++;
|
||||
(*dstBufLen)++;
|
||||
}
|
||||
*(*dstBuf) = '\0';
|
||||
}
|
||||
|
||||
static void BslBase64EncodeProcess(BSL_Base64Ctx *ctx, const uint8_t **srcBuf, uint32_t *srcBufLen,
|
||||
char *dstBuf, uint32_t *dstBufLen)
|
||||
{
|
||||
uint32_t remainLen = 0;
|
||||
const uint8_t *bufTmp = &(ctx->buf[0]);
|
||||
char *dstBufTmp = dstBuf;
|
||||
|
||||
if (ctx->num != 0) {
|
||||
remainLen = ctx->length - ctx->num;
|
||||
(void)memcpy_s(&(ctx->buf[ctx->num]), remainLen, *srcBuf, remainLen);
|
||||
BslBase64EncodeBlock(ctx, &bufTmp, srcBufLen, &dstBufTmp, dstBufLen, remainLen);
|
||||
*srcBuf += remainLen;
|
||||
remainLen = 0;
|
||||
}
|
||||
|
||||
const uint8_t *srcBufTmp = *srcBuf;
|
||||
/* Encoding every 48 characters. */
|
||||
while (*srcBufLen >= ctx->length) {
|
||||
BslBase64EncodeBlock(ctx, &srcBufTmp, srcBufLen, &dstBufTmp, dstBufLen, remainLen);
|
||||
}
|
||||
*srcBuf = srcBufTmp;
|
||||
}
|
||||
|
||||
static int32_t BslBase64DecodeCheck(const char src, uint32_t *paddingCnt)
|
||||
{
|
||||
uint32_t padding = 0;
|
||||
/* 66U is the header identifier '-' (invalid), and 66U or above are invalid characters beyond the range. */
|
||||
if (BASE64_DECODE_MAP_TABLE[(uint8_t)src] == 66U) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_BASE64_HEADER);
|
||||
return BSL_BASE64_HEADER;
|
||||
}
|
||||
if (BASE64_DECODE_MAP_TABLE[(uint8_t)src] > 66U) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
/* 65U is the padding character '=' and also EOF identifier. */
|
||||
if (BASE64_DECODE_MAP_TABLE[(uint8_t)src] == 65U) {
|
||||
if (*paddingCnt < BASE64_PAD_MAX) {
|
||||
padding++;
|
||||
} else { /* paddingCnt > 2 */
|
||||
BSL_ERR_PUSH_ERROR(BSL_BASE64_INVALID);
|
||||
return BSL_BASE64_INVALID;
|
||||
}
|
||||
}
|
||||
/* illegal behavior: data after padding. */
|
||||
if (*paddingCnt > 0 && BASE64_DECODE_MAP_TABLE[(uint8_t)src] < 64U) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_BASE64_DATA_AFTER_PADDING);
|
||||
return BSL_BASE64_DATA_AFTER_PADDING;
|
||||
}
|
||||
|
||||
*paddingCnt += padding;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_BASE64_Encode(const uint8_t *srcBuf, const uint32_t srcBufLen, char *dstBuf, uint32_t *dstBufLen)
|
||||
{
|
||||
int32_t ret = BslBase64EncodeParamsValidate(srcBuf, srcBufLen, (const char *)dstBuf, dstBufLen);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
BslBase64ArithEncodeProc(srcBuf, srcBufLen, dstBuf, dstBufLen); /* executes the encoding algorithm */
|
||||
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BslBase64Normalization(const char *srcBuf, const uint32_t srcBufLen, uint8_t *filterBuf,
|
||||
uint32_t *filterBufLen)
|
||||
{
|
||||
const uint8_t *tmp = (const uint8_t *)srcBuf;
|
||||
uint32_t validCnt = 0U;
|
||||
uint32_t expectLen = 0U;
|
||||
uint32_t idx;
|
||||
|
||||
/* Filter the characters \r\n, spaces, and '=' in the character string. */
|
||||
for (idx = 0U; idx < srcBufLen; idx++) {
|
||||
/* Check whether the characters are invalid characters in the Base64 mapping table. */
|
||||
if (BASE64_DECODE_MAP_TABLE[tmp[idx]] > 65U) {
|
||||
/* 66U is the status code of invalid characters. */
|
||||
return BSL_BASE64_INVALID_CHARACTER;
|
||||
}
|
||||
|
||||
/* Process the '=' */
|
||||
if (BASE64_DECODE_MAP_TABLE[tmp[idx]] == 65U) {
|
||||
/* 65U is the status code with the '=' */
|
||||
expectLen = ((validCnt + 3U) / 4U) * 4U;
|
||||
expectLen -= validCnt;
|
||||
expectLen += idx;
|
||||
if (expectLen > srcBufLen) {
|
||||
return BSL_BASE64_INVALID_CHARACTER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* copy valid characters */
|
||||
if (BASE64_DECODE_MAP_TABLE[tmp[idx]] < 64U) {
|
||||
/* [0,63] is the mapping index of the normal symbol. */
|
||||
filterBuf[validCnt] = tmp[idx];
|
||||
validCnt++;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t num = 0;
|
||||
/* Filter out the specified number of '=' when the '=' is encountered. */
|
||||
while (idx < expectLen) {
|
||||
if (BASE64_DECODE_MAP_TABLE[tmp[idx]] == 64U) {
|
||||
/* 64U indicates space. Filter out the spaces, '\r's and '\n's between the '='. */
|
||||
idx++;
|
||||
expectLen++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (BASE64_DECODE_MAP_TABLE[tmp[idx]] != 65U) {
|
||||
/* 65U indicates '=' */
|
||||
return BSL_BASE64_INVALID_CHARACTER;
|
||||
}
|
||||
idx++;
|
||||
num++;
|
||||
}
|
||||
|
||||
/* Filter out the '\r's, '\n's or spaces after valid characters. */
|
||||
while (idx < srcBufLen) {
|
||||
/* If a non \r\n or space is encountered again, it is an invalid base64 string. */
|
||||
if (BASE64_DECODE_MAP_TABLE[tmp[idx]] != 64U) {
|
||||
return BSL_BASE64_INVALID_CHARACTER;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
if (validCnt < (BASE64_DECODE_BYTES - BASE64_PAD_MAX)) { /* less than 2 valid characters cannot be decoded */
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
if ((validCnt + num) % BASE64_DECODE_BYTES != 0) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_BASE64_INVALID_ENCODE);
|
||||
return BSL_BASE64_INVALID_ENCODE;
|
||||
}
|
||||
*filterBufLen = validCnt;
|
||||
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
/* can ensure that dstBuf and dstBufLen are sufficient and that srcBuf does not contain invalid characters */
|
||||
static int32_t BslBase64DecodeBuffer(const uint8_t *srcBuf, const uint32_t srcBufLen, uint8_t *dstBuf,
|
||||
uint32_t *dstBufLen)
|
||||
{
|
||||
uint32_t idx = 0U;
|
||||
uint32_t tmpLen;
|
||||
const uint8_t *tmp = srcBuf;
|
||||
|
||||
for (tmpLen = srcBufLen; tmpLen > 4U; tmpLen -= 4U) {
|
||||
dstBuf[idx] = (BASE64_DECODE_MAP_TABLE[tmp[0U]] << 2U) | (BASE64_DECODE_MAP_TABLE[tmp[1U]] >> 4U);
|
||||
idx++;
|
||||
dstBuf[idx] = (BASE64_DECODE_MAP_TABLE[tmp[1U]] << 4U) | (BASE64_DECODE_MAP_TABLE[tmp[2U]] >> 2U);
|
||||
idx++;
|
||||
dstBuf[idx] = (BASE64_DECODE_MAP_TABLE[tmp[2U]] << 6U) | BASE64_DECODE_MAP_TABLE[tmp[3U]];
|
||||
idx++;
|
||||
tmp = &tmp[4U];
|
||||
}
|
||||
|
||||
/* processing of less than four characters */
|
||||
if (tmpLen > 1U) {
|
||||
/* process the case of one character */
|
||||
dstBuf[idx] = (BASE64_DECODE_MAP_TABLE[tmp[0U]] << 2U) | (BASE64_DECODE_MAP_TABLE[tmp[1U]] >> 4U);
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (tmpLen > 2U) {
|
||||
/* process the case of two characters */
|
||||
dstBuf[idx] = (BASE64_DECODE_MAP_TABLE[tmp[1U]] << 4U) | (BASE64_DECODE_MAP_TABLE[tmp[2U]] >> 2U);
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (tmpLen > 3U) {
|
||||
/* process the case of three characters */
|
||||
dstBuf[idx] = (BASE64_DECODE_MAP_TABLE[tmp[2U]] << 6U) | BASE64_DECODE_MAP_TABLE[tmp[3U]];
|
||||
idx++;
|
||||
}
|
||||
*dstBufLen = idx;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BslBase64ArithDecodeProc(const char *srcBuf, const uint32_t srcBufLen, uint8_t *dstBuf,
|
||||
uint32_t *dstBufLen)
|
||||
{
|
||||
uint8_t *buf = NULL;
|
||||
uint32_t bufLen; /* length to be decoded after redundant characters are deleted */
|
||||
int32_t ret;
|
||||
|
||||
buf = BSL_SAL_Malloc((uint32_t)srcBufLen);
|
||||
if (buf == NULL) {
|
||||
return BSL_MALLOC_FAIL;
|
||||
}
|
||||
|
||||
/* Delete the extra white space characters (\r\n, space, '=') */
|
||||
ret = BslBase64Normalization(srcBuf, (const uint32_t)srcBufLen, buf, &bufLen);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_SAL_FREE(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Decode the base64 character string. */
|
||||
ret = BslBase64DecodeBuffer(buf, (const uint32_t)bufLen, dstBuf, dstBufLen);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_SAL_FREE(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BSL_SAL_FREE(buf);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
/* Ensure that dstBuf and dstBufLen are correctly created. */
|
||||
int32_t BSL_BASE64_Decode(const char *srcBuf, const uint32_t srcBufLen, uint8_t *dstBuf, uint32_t *dstBufLen)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
/* An error is returned when a parameter is abnormal. */
|
||||
if (srcBuf == NULL || dstBuf == NULL || dstBufLen == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
|
||||
/* The length of dstBuf of the user must be at least (srcBufLen+3)/4*3. */
|
||||
if (*dstBufLen < BSL_BASE64_DEC_ENOUGH_LEN(srcBufLen)) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_BASE64_BUF_NOT_ENOUGH);
|
||||
return BSL_BASE64_BUF_NOT_ENOUGH;
|
||||
}
|
||||
|
||||
ret = BslBase64ArithDecodeProc(srcBuf, srcBufLen, dstBuf, dstBufLen); /* start decoding */
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_BASE64_EncodeInit(BSL_Base64Ctx *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
ctx->length = HITLS_BASE64_CTX_LENGTH;
|
||||
ctx->num = 0;
|
||||
ctx->flags = 0;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_BASE64_EncodeUpdate(BSL_Base64Ctx *ctx, const uint8_t *srcBuf, uint32_t srcBufLen,
|
||||
char *dstBuf, uint32_t *dstBufLen)
|
||||
{
|
||||
/* ensure the validity of dstBuf */
|
||||
if (ctx == NULL || srcBuf == NULL || dstBuf == NULL || srcBufLen == 0 || dstBufLen == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
if (ctx->length != HITLS_BASE64_CTX_LENGTH) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
/* By default, the user selects the line feed, considers the terminator,
|
||||
and checks whether the length meets the (srcBufLen + ctx->num)/48*65+1 requirement. */
|
||||
if (*dstBufLen < ((srcBufLen + ctx->num) / HITLS_BASE64_CTX_LENGTH * (BASE64_DECODE_BLOCKSIZE + 1) + 1)) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_BASE64_BUF_NOT_ENOUGH);
|
||||
return BSL_BASE64_BUF_NOT_ENOUGH;
|
||||
}
|
||||
|
||||
*dstBufLen = 0;
|
||||
|
||||
/* If srcBuf is too short for a buf, store it in the buf first. */
|
||||
if (srcBufLen < ctx->length - ctx->num) {
|
||||
(void)memcpy_s(&(ctx->buf[ctx->num]), srcBufLen, srcBuf, srcBufLen);
|
||||
ctx->num += srcBufLen;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
BslBase64EncodeProcess(ctx, &srcBuf, &srcBufLen, dstBuf, dstBufLen);
|
||||
|
||||
/* If the remaining bytes are less than 48 bytes, store the bytes in the buf and wait for next processing. */
|
||||
if (srcBufLen != 0) {
|
||||
/* Ensure that srcBufLen < 48 */
|
||||
(void)memcpy_s(&(ctx->buf[0]), srcBufLen, srcBuf, srcBufLen);
|
||||
}
|
||||
ctx->num = srcBufLen;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_BASE64_EncodeFinal(BSL_Base64Ctx *ctx, char *dstBuf, uint32_t *dstBufLen)
|
||||
{
|
||||
uint32_t tmpDstLen = 0;
|
||||
if (ctx == NULL || dstBuf == NULL || dstBufLen == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
if (ctx->num == 0) {
|
||||
*dstBufLen = 0;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
if (*dstBufLen < BSL_BASE64_ENC_ENOUGH_LEN((ctx->num))) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_BASE64_BUF_NOT_ENOUGH);
|
||||
return BSL_BASE64_BUF_NOT_ENOUGH;
|
||||
}
|
||||
|
||||
BslBase64ArithEncodeProc((const uint8_t *)ctx->buf, ctx->num, dstBuf, &tmpDstLen);
|
||||
if ((ctx->flags & BSL_BASE64_FLAGS_NO_NEWLINE) == 0) {
|
||||
dstBuf[tmpDstLen++] = '\n';
|
||||
}
|
||||
dstBuf[tmpDstLen] = '\0';
|
||||
*dstBufLen = tmpDstLen;
|
||||
ctx->num = 0;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_BASE64_DecodeInit(BSL_Base64Ctx *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
ctx->num = 0;
|
||||
ctx->length = 0;
|
||||
ctx->flags = 0;
|
||||
ctx->paddingCnt = 0;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_BASE64_DecodeUpdate(BSL_Base64Ctx *ctx, const char *srcBuf, const uint32_t srcBufLen,
|
||||
uint8_t *dstBuf, uint32_t *dstBufLen)
|
||||
{
|
||||
if (ctx == NULL || srcBuf == NULL || dstBuf == NULL || srcBufLen == 0 || dstBufLen == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
/* Estimated maximum value. By default, the input srcBuf is without line feed. Each line contains 64 characters.
|
||||
Check whether the length meets the (srcBufLen + ctx->num)/64*48 requirement. */
|
||||
if (*dstBufLen < ((srcBufLen + ctx->num) / BASE64_DECODE_BLOCKSIZE * HITLS_BASE64_CTX_LENGTH)) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_BASE64_BUF_NOT_ENOUGH);
|
||||
return BSL_BASE64_BUF_NOT_ENOUGH;
|
||||
}
|
||||
|
||||
uint32_t num = ctx->num;
|
||||
uint32_t totalLen = 0;
|
||||
uint32_t decodeLen = 0;
|
||||
uint8_t *tmpBuf = ctx->buf;
|
||||
int32_t ret = BSL_SUCCESS;
|
||||
uint8_t *dstTmp = dstBuf;
|
||||
|
||||
for (uint32_t i = 0U; i < srcBufLen; i++) {
|
||||
ret = BslBase64DecodeCheck(srcBuf[i], &ctx->paddingCnt);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
*dstBufLen = 0;
|
||||
if (ret == BSL_BASE64_HEADER) {
|
||||
*dstBufLen = totalLen;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (BASE64_DECODE_MAP_TABLE[(uint8_t)srcBuf[i]] < 64U) { /* 0U ~ 63U are valid characters */
|
||||
/* If num >= 64, it indicates that someone has modified the ctx.
|
||||
If this happens, refuse to write any more data. */
|
||||
if (num >= BASE64_DECODE_BLOCKSIZE) {
|
||||
*dstBufLen = 0;
|
||||
ctx->num = num;
|
||||
BSL_ERR_PUSH_ERROR(BSL_BASE64_ILLEGALLY_MODIFIED);
|
||||
return BSL_BASE64_ILLEGALLY_MODIFIED;
|
||||
}
|
||||
tmpBuf[num++] = (uint8_t)srcBuf[i]; /* save valid base64 characters */
|
||||
}
|
||||
|
||||
/* A round of block decoding is performed every time the num reaches 64, and then the buf is cleared. */
|
||||
if (num == BASE64_DECODE_BLOCKSIZE) {
|
||||
ret = BslBase64DecodeBuffer(tmpBuf, num, dstTmp, &decodeLen);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
*dstBufLen = 0;
|
||||
ctx->num = 0;
|
||||
BSL_ERR_PUSH_ERROR(BSL_BASE64_DECODE_FAILED);
|
||||
return BSL_BASE64_DECODE_FAILED;
|
||||
}
|
||||
num = 0;
|
||||
totalLen += decodeLen;
|
||||
dstTmp += decodeLen;
|
||||
}
|
||||
}
|
||||
*dstBufLen = totalLen;
|
||||
ctx->num = num;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_BASE64_DecodeFinal(BSL_Base64Ctx *ctx, uint8_t *dstBuf, uint32_t *dstBufLen)
|
||||
{
|
||||
int32_t ret = BSL_SUCCESS;
|
||||
uint32_t totalLen = 0;
|
||||
|
||||
if (ctx == NULL || dstBuf == NULL || dstBufLen == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
|
||||
if (ctx->num == 0) {
|
||||
*dstBufLen = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (*dstBufLen < BSL_BASE64_DEC_ENOUGH_LEN((ctx->num))) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_BASE64_BUF_NOT_ENOUGH);
|
||||
return BSL_BASE64_BUF_NOT_ENOUGH;
|
||||
}
|
||||
|
||||
ret = BslBase64DecodeBuffer((const uint8_t *)ctx->buf, ctx->num, dstBuf, &totalLen);
|
||||
ctx->num = 0;
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_BASE64_DECODE_FAILED);
|
||||
return BSL_BASE64_DECODE_FAILED;
|
||||
}
|
||||
|
||||
*dstBufLen = totalLen;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_BASE64_SetFlags(BSL_Base64Ctx *ctx, uint32_t flags)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
ctx->flags |= flags;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_Base64GetNum(BSL_Base64Ctx *ctx, uint32_t *num)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
*num = ctx->num;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
#endif /* HITLS_BSL_BASE64 */
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef BSL_ERR_INTERNAL_H
|
||||
#define BSL_ERR_INTERNAL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hitls_build.h"
|
||||
#include "bsl_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_BSL_ERR
|
||||
|
||||
/**
|
||||
* @ingroup bsl_err
|
||||
* @brief Save the error information to the error information stack.
|
||||
*
|
||||
* @par Description:
|
||||
* Save the error information to the error information stack.
|
||||
*
|
||||
* @attention err cannot be 0.
|
||||
* @param err [IN] Error code. The most significant 16 bits indicate the submodule ID,
|
||||
* and the least significant 16 bits indicate the error ID.
|
||||
* @param file [IN] File name, excluding the directory path
|
||||
* @param lineNo [IN] Number of the line where the error occurs.
|
||||
*/
|
||||
void BSL_ERR_PushError(int32_t err, const char *file, uint32_t lineNo);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_err
|
||||
* @brief Save the error information to the error information stack.
|
||||
*
|
||||
* @par Description:
|
||||
* Save the error information to the error information stack.
|
||||
*
|
||||
* @attention e cannot be 0.
|
||||
*/
|
||||
#define BSL_ERR_PUSH_ERROR(e) BSL_ERR_PushError((e), __FILENAME__, __LINE__)
|
||||
|
||||
#else
|
||||
|
||||
#define BSL_ERR_PUSH_ERROR(e)
|
||||
|
||||
#endif /* HITLS_BSL_ERR */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BSL_ERR_INTERNAL_H
|
||||
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_ERR
|
||||
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_log_internal.h"
|
||||
#include "bsl_log.h"
|
||||
#include "bsl_binlog_id.h"
|
||||
#include "avl.h"
|
||||
|
||||
// Maximum height of the AVL tree.
|
||||
#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) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05001, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"avl tree height exceed max limit", 0, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
node->height = GetMaxHeight(leftHeight, rightHeight) + 1u;
|
||||
}
|
||||
}
|
||||
|
||||
BSL_AvlTree *BSL_AVL_MakeLeafNode(BSL_ElementData data)
|
||||
{
|
||||
BSL_AvlTree *curNode = (BSL_AvlTree *)BSL_SAL_Malloc(sizeof(BSL_AvlTree));
|
||||
if (curNode == NULL) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05002, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"MALLOC for avl tree node failed", 0, 0, 0, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
curNode->height = 1;
|
||||
curNode->rightNode = NULL;
|
||||
curNode->leftNode = NULL;
|
||||
curNode->data = data;
|
||||
|
||||
return curNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AVL rotate left
|
||||
* @param root [IN] Root node to be rotated
|
||||
* @return rNode Root node after rotation
|
||||
*/
|
||||
static BSL_AvlTree *AVL_RotateLeft(BSL_AvlTree *root)
|
||||
{
|
||||
/* Rotate Left
|
||||
10 20
|
||||
5 20 --Rotate Left---> 10 30
|
||||
30 5 40
|
||||
40
|
||||
|
||||
In this case, the input root node is 10, and the output node is 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 rotate right
|
||||
* @param root [IN] Root node to be rotated
|
||||
* @return lNode Root node after rotation
|
||||
*/
|
||||
static BSL_AvlTree *AVL_RotateRight(BSL_AvlTree *root)
|
||||
{
|
||||
/* Rotate Right
|
||||
40 30
|
||||
/ \ / \
|
||||
30 50 --Rotate Right---> 20 40
|
||||
20 35 10 35 50
|
||||
10
|
||||
In this case, the input root node is 40, and the output node is 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 Right Balance
|
||||
* @param root [IN] Root node to be balanced
|
||||
* @return root: root node after balancing
|
||||
*/
|
||||
static BSL_AvlTree *AVL_RebalanceRight(BSL_AvlTree *root)
|
||||
{
|
||||
// The height difference between the left and right subtrees is only 1.
|
||||
if ((GetAvlTreeHeight(root->leftNode) + 1u) >= GetAvlTreeHeight(root->rightNode)) {
|
||||
UpdateAvlTreeHeight(root);
|
||||
return root;
|
||||
}
|
||||
/* The height of the left subtree is greater than that of the right subtree. Rotate right and then left. */
|
||||
BSL_AvlTree *curNode = root->rightNode;
|
||||
if (GetAvlTreeHeight(curNode->leftNode) > GetAvlTreeHeight(curNode->rightNode)) {
|
||||
root->rightNode = AVL_RotateRight(curNode);
|
||||
}
|
||||
return AVL_RotateLeft(root);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AVL Left Balance
|
||||
* @param root [IN] Root node to be balanced
|
||||
* @return root: root node after balancing
|
||||
*/
|
||||
static BSL_AvlTree *AVL_RebalanceLeft(BSL_AvlTree *root)
|
||||
{
|
||||
// The height difference between the left and right subtrees is only 1.
|
||||
if ((GetAvlTreeHeight(root->rightNode) + 1u) >= GetAvlTreeHeight(root->leftNode)) {
|
||||
UpdateAvlTreeHeight(root);
|
||||
return root;
|
||||
}
|
||||
/* The height of the right subtree is greater than that of the left subtree. Rotate left and then right. */
|
||||
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) {
|
||||
// If the nodeId is smaller than the root nodeId, insert the left subtree.
|
||||
root->leftNode = BSL_AVL_InsertNode(root->leftNode, nodeId, node);
|
||||
|
||||
return AVL_RebalanceLeft(root);
|
||||
} else if (root->nodeId < nodeId) {
|
||||
// If the nodeId is greater than the root nodeId, insert the right subtree.
|
||||
root->rightNode = BSL_AVL_InsertNode(root->rightNode, nodeId, node);
|
||||
|
||||
return AVL_RebalanceRight(root);
|
||||
}
|
||||
|
||||
/* if the keys are the same and cannot be inserted */
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05003, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"AVL tree insert key nodeId(%llu) already exist", nodeId, 0, 0, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BSL_AvlTree *BSL_AVL_SearchNode(BSL_AvlTree *root, uint64_t nodeId)
|
||||
{
|
||||
BSL_AvlTree *curNode = root;
|
||||
while (curNode != NULL) {
|
||||
// match the node
|
||||
if (curNode->nodeId == nodeId) {
|
||||
break;
|
||||
} else if (curNode->nodeId > nodeId) {
|
||||
// If the nodeId is smaller than the root nodeId, search the left subtree.
|
||||
curNode = curNode->leftNode;
|
||||
} else {
|
||||
// If the nodeId is greater than the root nodeId, search the right subtree.
|
||||
curNode = curNode->rightNode;
|
||||
}
|
||||
}
|
||||
|
||||
// If the specified node cannot be found, NULL is returned.
|
||||
return curNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete the specified AVL node that has both the left and right subnodes.
|
||||
* @param rmNodeChild [IN] Child node of the AVL node to be deleted
|
||||
* removeNode [IN] Avl node to be deleted.
|
||||
* @return root Return the deleted root node of the AVL tree.
|
||||
*/
|
||||
static BSL_AvlTree *AVL_DeleteNodeWithTwoChilds(BSL_AvlTree *rmNodeChild, BSL_AvlTree *removeNode)
|
||||
{
|
||||
if (rmNodeChild == NULL || removeNode == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (rmNodeChild->rightNode == NULL) {
|
||||
// Connect the left node and the grandfather node regardless of whether rmNodeChild has a left node.
|
||||
BSL_AvlTree *curNode = rmNodeChild->leftNode;
|
||||
removeNode->nodeId = rmNodeChild->nodeId;
|
||||
removeNode->data = rmNodeChild->data;
|
||||
|
||||
BSL_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) {
|
||||
// Both the left and right nodes are NULL.
|
||||
AVL_FreeData(root->data, func);
|
||||
BSL_SAL_FREE(root);
|
||||
return NULL;
|
||||
} else {
|
||||
// Only have the right node.
|
||||
BSL_AvlTree *curNode = root->rightNode;
|
||||
AVL_FreeData(root->data, func);
|
||||
BSL_SAL_FREE(root);
|
||||
return (curNode);
|
||||
}
|
||||
} else if (root->rightNode == NULL) {
|
||||
// Only have the right node.
|
||||
BSL_AvlTree *curNode = root->leftNode;
|
||||
AVL_FreeData(root->data, func);
|
||||
BSL_SAL_FREE(root);
|
||||
return (curNode);
|
||||
} else {
|
||||
// There are left and right nodes.
|
||||
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);
|
||||
BSL_SAL_FREE(root);
|
||||
}
|
||||
|
||||
#endif /* HITLS_BSL_ERR */
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef AVL_H
|
||||
#define AVL_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_ERR
|
||||
|
||||
#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_err
|
||||
* @brief Create a tree node.
|
||||
*
|
||||
* @par Description:
|
||||
* Create a tree node and set node data.
|
||||
*
|
||||
* @attention None
|
||||
* @param data [IN] Data pointer of the tree node
|
||||
* @retval BSL_AvlTree *curNode node returned after the application is successful.
|
||||
* NULL application failed
|
||||
*/
|
||||
BSL_AvlTree *BSL_AVL_MakeLeafNode(BSL_ElementData data);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_err
|
||||
* @brief Search for a node.
|
||||
*
|
||||
* @par Description:
|
||||
* Query the node in the AVL tree by nodeId.
|
||||
*
|
||||
* @attention None
|
||||
* @param root [IN] Pointer to the root node of the tree
|
||||
* @param nodeId [IN] node ID of the tree, as the key
|
||||
* @retval NULL No corresponding node is found.
|
||||
* @retval not NULL Pointer to the corresponding node.
|
||||
*/
|
||||
BSL_AvlTree *BSL_AVL_SearchNode(BSL_AvlTree *root, uint64_t nodeId);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_err
|
||||
* @brief Create a node in the tree.
|
||||
*
|
||||
* @par Description:
|
||||
* Create a node in the tree.
|
||||
*
|
||||
* @attention If the nodeId already exists, the insertion fails.
|
||||
* @param root [IN] Pointer to the root node of the tree.
|
||||
* @param nodeId [IN] as the key of the created node
|
||||
* @param node [IN] Tree node
|
||||
* @retval The root node of a non-null tree or subtree
|
||||
*/
|
||||
BSL_AvlTree *BSL_AVL_InsertNode(BSL_AvlTree *root, uint64_t nodeId, BSL_AvlTree *node);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_err
|
||||
* @brief Delete a specific tree node.
|
||||
*
|
||||
* @par Description:
|
||||
* Delete the nodeId corresponding tree node.
|
||||
*
|
||||
* @attention None
|
||||
* @param root [IN] Pointer to the root node of the tree.
|
||||
* @param nodeId [IN] Key of the node to be deleted
|
||||
* @param func [IN] Pointer to the function that releases the data of the deleted node.
|
||||
* @retval NULL All nodes in the tree have been deleted.
|
||||
* @retval not NULL Pointer to the root node of a tree or subtree.
|
||||
*/
|
||||
BSL_AvlTree *BSL_AVL_DeleteNode(BSL_AvlTree *root, uint64_t nodeId, BSL_AVL_DATA_FREE_FUNC func);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_err
|
||||
* @brief Delete all nodes from the tree.
|
||||
*
|
||||
* @par Description:
|
||||
* Delete all nodes in the tree.
|
||||
*
|
||||
* @attention None
|
||||
* @param root [IN] Pointer to the root node of the tree
|
||||
* @param func [IN] Pointer to the function that releases the data of the deleted node.
|
||||
*/
|
||||
void BSL_AVL_DeleteTree(BSL_AvlTree *root, BSL_AVL_DATA_FREE_FUNC func);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_BSL_ERR */
|
||||
|
||||
#endif // AVL_H
|
||||
@@ -0,0 +1,534 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_ERR
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "securec.h"
|
||||
#include "bsl_log_internal.h"
|
||||
#include "bsl_log.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "avl.h"
|
||||
#include "bsl_err.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_binlog_id.h"
|
||||
#include "bsl_err_internal.h"
|
||||
|
||||
#define ERR_FLAG_POP_MARK 0x01
|
||||
|
||||
/* Error information stack size */
|
||||
#define SAL_MAX_ERROR_STACK 20
|
||||
|
||||
/* Error information stack */
|
||||
typedef struct {
|
||||
/* Current point location to the stack. When the value is -1, the stack is empty. */
|
||||
uint16_t bottom; /* Stack bottom */
|
||||
uint16_t top; /* Stack top */
|
||||
/* Prevent error stacks from being cleared. Currently, this parameter is used in asynchronous cases. */
|
||||
uint32_t flag;
|
||||
|
||||
/* Store the error code information of a specific thread */
|
||||
int32_t errorStack[SAL_MAX_ERROR_STACK];
|
||||
|
||||
/* Error code flag, which is used to partially clear and prevent side channel attack. */
|
||||
uint32_t errorFlags[SAL_MAX_ERROR_STACK];
|
||||
|
||||
/* store the error file name. */
|
||||
const char *filename[SAL_MAX_ERROR_STACK];
|
||||
|
||||
/* store the line number of the file where the error occurs */
|
||||
uint32_t line[SAL_MAX_ERROR_STACK];
|
||||
} ErrorCodeStack;
|
||||
|
||||
/* Avl tree root node of the error stack. */
|
||||
static BSL_AvlTree *g_avlRoot = NULL;
|
||||
|
||||
/* Error description root node */
|
||||
static BSL_AvlTree *g_descRoot = NULL;
|
||||
|
||||
/* Current number of AVL nodes */
|
||||
static uint32_t g_avlNodeCount = 0;
|
||||
|
||||
/* Maximum number of nodes allowed by the AVL tree */
|
||||
static uint32_t g_maxAvlNodes = 0x0000FFFF;
|
||||
|
||||
/* Check the initialization status. 0 means false, if the value is not 0, it means true. Run once. */
|
||||
static uint32_t g_isErrInit = 0;
|
||||
|
||||
/* Handle of the thread lock */
|
||||
static BSL_SAL_ThreadLockHandle g_errLock = NULL;
|
||||
|
||||
static void ErrAutoInit(void)
|
||||
{
|
||||
/* Attempting self-initialization in abnormal conditions */
|
||||
(void)BSL_ERR_Init();
|
||||
}
|
||||
|
||||
int32_t BSL_ERR_Init(void)
|
||||
{
|
||||
if (g_errLock != NULL) {
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
return BSL_SAL_ThreadLockNew(&g_errLock);
|
||||
}
|
||||
|
||||
void BSL_ERR_DeInit(void)
|
||||
{
|
||||
g_isErrInit = 0;
|
||||
if (g_errLock == NULL) {
|
||||
return;
|
||||
}
|
||||
BSL_SAL_ThreadLockFree(g_errLock);
|
||||
g_errLock = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
BSL_SAL_FREE(data);
|
||||
}
|
||||
|
||||
static ErrorCodeStack *GetStack(void)
|
||||
{
|
||||
const uint64_t threadId = BSL_SAL_ThreadGetId();
|
||||
BSL_AvlTree *curNode = BSL_AVL_SearchNode(g_avlRoot, threadId);
|
||||
if (curNode != NULL) {
|
||||
/* If an error stack exists, directly returned. */
|
||||
return curNode->data;
|
||||
}
|
||||
/* need to create an error stack */
|
||||
if (g_avlNodeCount >= g_maxAvlNodes) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05004, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"New Avl Node failed.", 0, 0, 0, 0);
|
||||
return NULL;
|
||||
}
|
||||
ErrorCodeStack *stack = (ErrorCodeStack *)BSL_SAL_Calloc(1, sizeof(ErrorCodeStack));
|
||||
if (stack == NULL) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05005, 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);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05006, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"avl insert node failed, threadId %lu", threadId, 0, 0, 0);
|
||||
return NULL;
|
||||
}
|
||||
g_avlNodeCount++;
|
||||
/* upper layer has ensured that the threadId node does not exist. */
|
||||
g_avlRoot = BSL_AVL_InsertNode(g_avlRoot, threadId, node);
|
||||
return stack;
|
||||
}
|
||||
|
||||
void BSL_ERR_PushError(int32_t err, const char *file, uint32_t lineNo)
|
||||
{
|
||||
if (err == BSL_SUCCESS) {
|
||||
/* push success is not allowed. */
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t ret = BSL_SAL_ThreadWriteLock(g_errLock);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05007, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"acquire lock failed when pushing error, threadId %llu, error code %d", BSL_SAL_ThreadGetId(), 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;
|
||||
}
|
||||
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
}
|
||||
|
||||
void BSL_ERR_ClearError(void)
|
||||
{
|
||||
(void)BSL_SAL_ThreadRunOnce(&g_isErrInit, ErrAutoInit);
|
||||
|
||||
uint64_t threadId = BSL_SAL_ThreadGetId();
|
||||
int32_t ret = BSL_SAL_ThreadWriteLock(g_errLock);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05008, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"acquire lock failed when clearing error, threadId %llu", threadId, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
BSL_AvlTree *curNode = BSL_AVL_SearchNode(g_avlRoot, threadId);
|
||||
if (curNode != NULL) {
|
||||
/* Will not be NULL. */
|
||||
ErrorCodeStack *errStack = curNode->data;
|
||||
if (errStack->flag == 0) {
|
||||
StackReset(errStack);
|
||||
}
|
||||
}
|
||||
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
}
|
||||
|
||||
void BSL_ERR_RemoveErrorStack(bool isRemoveAll)
|
||||
{
|
||||
(void)BSL_SAL_ThreadRunOnce(&g_isErrInit, ErrAutoInit);
|
||||
|
||||
int32_t ret = BSL_SAL_ThreadWriteLock(g_errLock);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05009, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"acquire lock failed when removing error stack, threadId %llu", BSL_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 = BSL_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
}
|
||||
|
||||
/* Obtain the index. 'last' indicates that the last or first error code is obtained. */
|
||||
static 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;
|
||||
}
|
||||
|
||||
/* If clr is true, the external operation is get. If clr is false, the external operation is peek.
|
||||
The get operation cleans up after the error information is obtained, while the peek operation does not.
|
||||
If last is true, the last error code at the top of the stack is obtained.
|
||||
If last is false, the first error code at the bottom of the stack is obtained. */
|
||||
static int32_t GetErrorInfo(const char **file, uint32_t *lineNo, bool clr, bool last)
|
||||
{
|
||||
uint16_t idx;
|
||||
|
||||
int32_t ret = BSL_SAL_ThreadReadLock(g_errLock);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return BSL_ERR_ERR_ACQUIRE_READ_LOCK_FAIL;
|
||||
}
|
||||
|
||||
if (g_avlRoot == NULL) {
|
||||
/* If avlRoot is empty, no thread push error. Therefore, error should be success. */
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
const uint64_t threadId = BSL_SAL_ThreadGetId();
|
||||
BSL_AvlTree *curNode = BSL_AVL_SearchNode(g_avlRoot, threadId);
|
||||
if (curNode == NULL) {
|
||||
/* If curNode is empty, the current thread does not have push error. Therefore, error should be success. */
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
ErrorCodeStack *errStack = curNode->data; /* will not be null */
|
||||
|
||||
idx = GetIndex(errStack, last);
|
||||
if (errStack->errorStack[idx] == 0) { /* error stack is empty */
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t errorCode = errStack->errorStack[idx]; /* Obtain the specified error ID. */
|
||||
uint32_t fileLine = errStack->line[idx]; /* Obtain the specified line number. */
|
||||
const char *f = errStack->filename[idx]; /* Obtain the specified file name. */
|
||||
if (clr) {
|
||||
StackResetIndex(errStack, idx);
|
||||
if (last) {
|
||||
errStack->top = idx;
|
||||
} else {
|
||||
errStack->bottom = (idx + 1) % SAL_MAX_ERROR_STACK;
|
||||
}
|
||||
}
|
||||
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
|
||||
if (file != NULL && lineNo != NULL) { /* both together, there's no point in getting only one of them. */
|
||||
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);
|
||||
}
|
||||
|
||||
static int32_t AddErrDesc(const BSL_ERR_Desc *desc)
|
||||
{
|
||||
if (desc->error < 0) {
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
BSL_AvlTree *curNode = BSL_AVL_SearchNode(g_descRoot, (uint64_t)desc->error);
|
||||
if (curNode != NULL) {
|
||||
curNode->data = (BSL_ElementData)(uintptr_t)(desc->string);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
BSL_AvlTree *node = BSL_AVL_MakeLeafNode((BSL_ElementData)(uintptr_t)(desc->string));
|
||||
if (node == NULL) {
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
g_descRoot = BSL_AVL_InsertNode(g_descRoot, (uint64_t)desc->error, node);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_ERR_AddErrStringBatch(const BSL_ERR_Desc *descList, uint32_t num)
|
||||
{
|
||||
if (descList == NULL || num == 0) {
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
int32_t ret = BSL_SAL_ThreadWriteLock(g_errLock);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
uint32_t i;
|
||||
for (i = 0; i < num; i++) {
|
||||
ret = AddErrDesc(&descList[i]);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
exit:
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void BSL_ERR_RemoveErrStringBatch(void)
|
||||
{
|
||||
int32_t ret = BSL_SAL_ThreadWriteLock(g_errLock);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05010, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"acquire lock failed when removing error string, threadId %llu", BSL_SAL_ThreadGetId(), 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
if (g_descRoot != NULL) {
|
||||
BSL_AVL_DeleteTree(g_descRoot, NULL);
|
||||
g_descRoot = NULL;
|
||||
}
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
}
|
||||
|
||||
const char *BSL_ERR_GetString(int32_t error)
|
||||
{
|
||||
if (error < 0) {
|
||||
return NULL;
|
||||
}
|
||||
int32_t ret = BSL_SAL_ThreadWriteLock(g_errLock);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
if (g_descRoot == NULL) {
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
return NULL;
|
||||
}
|
||||
BSL_AvlTree *curNode = BSL_AVL_SearchNode(g_descRoot, (uint64_t)error);
|
||||
if (curNode == NULL) {
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
return NULL;
|
||||
}
|
||||
const char *str = curNode->data;
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
return str;
|
||||
}
|
||||
|
||||
static int32_t BSL_LIST_WriteLockCreate(ErrorCodeStack **errStack, uint32_t *top)
|
||||
{
|
||||
int32_t ret = BSL_SAL_ThreadWriteLock(g_errLock);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return BSL_ERR_ERR_ACQUIRE_WRITE_LOCK_FAIL;
|
||||
}
|
||||
|
||||
if (g_avlRoot == NULL) {
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
return BSL_ERR_ERR_NO_STACK;
|
||||
}
|
||||
|
||||
const uint64_t threadId = BSL_SAL_ThreadGetId();
|
||||
BSL_AvlTree *curNode = BSL_AVL_SearchNode(g_avlRoot, threadId);
|
||||
if (curNode == NULL) {
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
return BSL_ERR_ERR_NO_STACK;
|
||||
}
|
||||
|
||||
*errStack = curNode->data; /* will not be null */
|
||||
if (top == NULL) {
|
||||
return ret;
|
||||
}
|
||||
*top = (*errStack)->top - 1;
|
||||
if (*top >= SAL_MAX_ERROR_STACK) {
|
||||
*top = SAL_MAX_ERROR_STACK - 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_ERR_SetMark(void)
|
||||
{
|
||||
ErrorCodeStack *errStack = NULL;
|
||||
uint32_t top = 0;
|
||||
int32_t ret = BSL_LIST_WriteLockCreate(&errStack, &top);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (errStack->errorStack[top] == 0) { /* error stack is empty */
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
return BSL_ERR_ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
errStack->errorFlags[top] |= ERR_FLAG_POP_MARK;
|
||||
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_ERR_PopToMark(void)
|
||||
{
|
||||
ErrorCodeStack *errStack = NULL;
|
||||
uint32_t top = 0;
|
||||
int32_t ret = BSL_LIST_WriteLockCreate(&errStack, &top);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (errStack->errorStack[top] != 0 && ((errStack->errorFlags[top] & ERR_FLAG_POP_MARK) == 0)) {
|
||||
StackResetIndex(errStack, top);
|
||||
top--;
|
||||
if (top >= SAL_MAX_ERROR_STACK) {
|
||||
top = SAL_MAX_ERROR_STACK - 1;
|
||||
}
|
||||
}
|
||||
errStack->top = (top + 1) % SAL_MAX_ERROR_STACK;
|
||||
|
||||
if (errStack->errorStack[top] == 0) {
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
return BSL_ERR_ERR_NO_MARK;
|
||||
}
|
||||
|
||||
errStack->errorFlags[top] &= ~ERR_FLAG_POP_MARK;
|
||||
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_ERR_ClearLastMark(void)
|
||||
{
|
||||
ErrorCodeStack *errStack = NULL;
|
||||
uint32_t top = 0;
|
||||
int32_t ret = BSL_LIST_WriteLockCreate(&errStack, &top);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (errStack->errorStack[top] != 0 && ((errStack->errorFlags[top] & ERR_FLAG_POP_MARK) == 0)) {
|
||||
top--;
|
||||
if (top >= SAL_MAX_ERROR_STACK) {
|
||||
top = SAL_MAX_ERROR_STACK - 1;
|
||||
}
|
||||
}
|
||||
errStack->errorFlags[top] &= ~ERR_FLAG_POP_MARK;
|
||||
|
||||
BSL_SAL_ThreadUnlock(g_errLock);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* HITLS_BSL_ERR */
|
||||
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup bsl_hash hash table
|
||||
* @ingroup bsl
|
||||
*/
|
||||
|
||||
#ifndef BSL_HASH_H
|
||||
#define BSL_HASH_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_HASH
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bsl_hash_list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Handle of the hash table, which indicates the elements contained in the hash table.
|
||||
*/
|
||||
typedef struct BSL_HASH_Info BSL_HASH_Hash;
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Definition of the iterator of the hash table, pointing to the hash node.
|
||||
*/
|
||||
typedef struct BSL_HASH_TagNode *BSL_HASH_Iterator;
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Generates a hash table index based on the entered key.
|
||||
* @param key [IN] hash key
|
||||
* @param bktSize [IN] hash bucket size
|
||||
*/
|
||||
typedef uint32_t (*BSL_HASH_CodeCalcFunc)(uintptr_t key, uint32_t bktSize);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief This function is used to match the input data with the key.
|
||||
* Key1 stored in the hash table, and the key2 to be matched. If no, false is returned.
|
||||
* @param key1 [IN] Key stored in the hash table
|
||||
* @param key2 [IN] Key to be matched
|
||||
* @retval #true key1 matches key2.
|
||||
* @retval #false key1 and key2 do not match.
|
||||
*/
|
||||
typedef bool (*BSL_HASH_MatchFunc)(uintptr_t key1, uintptr_t key2);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Hash function.
|
||||
* @par Description: Calculate the hash value based on the key value.
|
||||
* The hash value does not modulate the size of the hash table and cannot be directly used for hash indexing.
|
||||
* @attention
|
||||
* 1. The key is the input parameter when the user invokes other interfaces.
|
||||
* 2. If the key is an integer, you can use this function as the hashFunc parameter when creating a hash.
|
||||
* @param key [IN] Key to be calculated.
|
||||
* @param keySize [IN] Size of the key value.
|
||||
* @retval #Hash value calculated based on the user key. The hash value is not modulated by the hash table size
|
||||
* and cannot be directly used for hash indexing.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
uint32_t BSL_HASH_CodeCalc(void *key, uint32_t keySize);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Default integer hash function.
|
||||
* @par Default integer hash function.
|
||||
* @attention
|
||||
* 1. The key parameter is the input parameter when the user invokes other interfaces.
|
||||
* 2. If the key is an integer, you can use this function as the hashFunc parameter when creating a hash.
|
||||
* @param key [IN] Key to be calculated.
|
||||
* @param bktSize [IN] Hash bucket size.
|
||||
* @retval #Hash value calculated based on the user key.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
uint32_t BSL_HASH_CodeCalcInt(uintptr_t key, uint32_t bktSize);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Default string hash function.
|
||||
* @par Default string hash function.
|
||||
* @attention
|
||||
* 1. The key is an input parameter when the user invokes other interfaces.
|
||||
* Ensure that the input key is a valid string start address.
|
||||
* 2. If the key is a string, you can use this function as the hashFunc parameter when creating a hash.
|
||||
* @param key [IN] Key to be calculated.
|
||||
* @param bktSize [IN] Hash bucket size.
|
||||
* @retval #Hash valueThe hash value calculated based on the user key.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
uint32_t BSL_HASH_CodeCalcStr(uintptr_t key, uint32_t bktSize);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Default integer matching function.
|
||||
* @par Default integer matching function.
|
||||
* @attention
|
||||
* 1. The key is the input parameter when the user invokes other interfaces.
|
||||
* 2. If the key is an integer, you can use this function as the matchFunc parameter when creating a hash.
|
||||
* @param key1 [IN] Key to be matched.
|
||||
* @param key2 [IN] Key to be matched.
|
||||
* @retval #true key1 matches key2.
|
||||
* @retval #false key1 and key2 do not match.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
bool BSL_HASH_MatchInt(uintptr_t key1, uintptr_t key2);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Default string matching function.
|
||||
* @par Default string matching function.
|
||||
* @attention
|
||||
* 1. Key1 is the input parameter when the user invokes other interfaces.
|
||||
* Ensure that the input key1 is a valid string start address.
|
||||
* 2. If the key is a string, you can use this function as the matchFunc parameter when creating the hash.
|
||||
* @param key1 [IN] Key to be matched.
|
||||
* @param key2 [IN] Key to be matched.
|
||||
* @retval #true key1 matches key2.
|
||||
* @retval #false key1 and key2 do not match.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
bool BSL_HASH_MatchStr(uintptr_t key1, uintptr_t key2);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Create a hash table and return the handle of the hash table.
|
||||
* @attention
|
||||
* 1. Copy functions for keys and data:
|
||||
* You do not need to register the copy function in the following case:
|
||||
* a) Data is the int type and the length <= sizeof(uintptr_t).
|
||||
* The copy function must be registered in the following cases:
|
||||
* a) Data is the int type, but the length is greater than sizeof(uintptr_t);
|
||||
* b) string;
|
||||
* c) User-defined data structure.
|
||||
* 2. About the free function: Simply put, if the duplicate function is registered,
|
||||
* the corresponding free function must be registered.
|
||||
* 3. Provide the default integer and string hash functions: #BSL_HASH_CodeCalcInt and #BSL_HASH_CodeCalcStr.
|
||||
* 4. Provide default integer and string matching functions: #BSL_HASH_MatchInt and #BSL_HASH_MatchStr.
|
||||
* @param bktSize [IN] Number of hash buckets.
|
||||
* @param hashCalcFunc [IN] Hash value calculation function.
|
||||
* If the value is NULL, the default key is an integer. Use #BSL_HASH_CodeCalcInt.
|
||||
* @param matchFunc [IN] hash key matching function.
|
||||
* If the value is NULL, the default key is an integer. Use #BSL_HASH_MatchInt.
|
||||
* @param keyFunc [IN] hash key copy and release function pair.
|
||||
* If the keyFunc->dupFunc is not registered, the key is an integer by default.
|
||||
* @param valueFunc [IN] hash data copy and release function pair.
|
||||
* If the user has not registered valueFunc->dupFunc, the data type is an integer by default.
|
||||
* @retval hash table handle. NULL indicates that the creation fails.
|
||||
* @par Dependency: None
|
||||
* @see #BSL_HASH_CodeCalcInt, #BSL_HASH_CodeCalcStr, #BSL_HASH_MatchInt, #BSL_HASH_MatchStr.
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
BSL_HASH_Hash *BSL_HASH_Create(uint32_t bktSize, BSL_HASH_CodeCalcFunc hashFunc, BSL_HASH_MatchFunc matchFunc,
|
||||
ListDupFreeFuncPair *keyFunc, ListDupFreeFuncPair *valueFunc);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Insert the hash data.
|
||||
* @par Description: Create a node and insert data (key and value) into the hash table.
|
||||
* @attention
|
||||
* 1. Duplicate keys are not supported.
|
||||
* 2. The key and value are integer values or addresses pointing to the user key or value.
|
||||
* 3. If the life cycle of the extended data is shorter than the life cycle of the node,
|
||||
* you need to register the copy function and release function when creating the hash table.
|
||||
* @param hash [IN] handle of the hash table
|
||||
* @param key [IN] key or address for storing the key
|
||||
* @param keySize [IN] Copy length of key. If the user has not registered the dupFunc, this parameter is not used.
|
||||
* @param value [IN] value or the address for storing the value.
|
||||
* @param valueSize [IN] Copy length of value. If user has not registered the dupFunc, this parameter is not used.
|
||||
* @retval #BSL_SUCCESS Succeeded in inserting the node.
|
||||
* @retval #BSL_INTERNAL_EXCEPTION Insertion fails.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
int32_t BSL_HASH_Insert(BSL_HASH_Hash *hash, uintptr_t key, uint32_t keySize, uintptr_t value, uint32_t valueSize);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Insert or update the hash data.
|
||||
* @par Description: This function is used to insert a nonexistent key into the hash table
|
||||
* or update the value corresponding to an existing key.
|
||||
* @attention
|
||||
* 1. Duplicate keys are supported.
|
||||
* 2. When the key does not exist, the usage of this function is the same as that of #BSL_HASH_Insert.
|
||||
* 3. When the key exists, this function updates the value.
|
||||
* @param hash [IN] Handle of the hash table.
|
||||
* @param key [IN] key or address for storing the key.
|
||||
* @param keySize [IN] Copy length of key. If the user has not registered the dupFunc, this parameter is not used.
|
||||
* @param value [IN] value or the address for storing the value.
|
||||
* @param valueSize [IN] Copy length of value. If user has not registered the dupFunc, this parameter is not used.
|
||||
* @retval #BSL_SUCCESS Succeeded in inserting or updating the node.
|
||||
* @retval #BSL_INTERNAL_EXCEPTION Failed to insert or update the node.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
int32_t BSL_HASH_Put(BSL_HASH_Hash *hash, uintptr_t key, uint32_t keySize, uintptr_t value, uint32_t valueSize);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Search for a node and return the node data.
|
||||
* @par Description: Searches for and returns node data based on the key.
|
||||
* @param hash [IN] Handle of the hash table.
|
||||
* @param key [IN] key or address for storing the key.
|
||||
* @param value [OUT] Data found.
|
||||
* @retval #BSL_SUCCESS found successfully.
|
||||
* @retval #BSL_INTERNAL_EXCEPTION query failed.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
int32_t BSL_HASH_At(const BSL_HASH_Hash *hash, uintptr_t key, uintptr_t *value);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Search for the iterator where the key is located.
|
||||
* @par Description: Searches for and returns the iterator where the key is located based on the key.
|
||||
* @param hash [IN] Handle of the hash table.
|
||||
* @param key [IN] key or address for storing the key.
|
||||
* @retval If the key exists, the iterator (pointing to the address of the node) where the key is located is returned.
|
||||
* In other cases, #BSL_HASH_IterEnd() is returned.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
BSL_HASH_Iterator BSL_HASH_Find(const BSL_HASH_Hash *hash, uintptr_t key);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Check whether the current hash table is empty.
|
||||
* @par Description: Check whether the current hash table is empty.
|
||||
* If the hash table is empty, true is returned. Otherwise, false is returned.
|
||||
* @param hash [IN] Handle of the hash table. The value range is valid pointer.
|
||||
* @retval #true, indicating that the hash table is empty.
|
||||
* @retval #false, indicating that the hash table is not empty.
|
||||
* @see #BSL_HASH_Size
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where the interface declaration is stored.
|
||||
*/
|
||||
bool BSL_HASH_Empty(const BSL_HASH_Hash *hash);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Obtain the number of nodes in the hash table.
|
||||
* @par Description: Obtains the number of nodes in the hash table and returns the number of nodes.
|
||||
* @param hash [IN] Handle of the hash table. The value range is valid pointer.
|
||||
* @retval Number of hash nodes.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
uint32_t BSL_HASH_Size(const BSL_HASH_Hash *hash);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Remove a specified node from the hash table.
|
||||
* @par Description: Find the node based on the key, delete the node (release it),
|
||||
* and release the memory of the corresponding node.
|
||||
* @param hash [IN] Handle of the hash table. The value range is a valid pointer.
|
||||
* @param key [IN] Remove a node key.
|
||||
* @retval If the key exists,
|
||||
* the next iterator (pointing to the address of the node) of the iterator where the key is located is returned.
|
||||
* Otherwise, #BSL_HASH_IterEnd() is returned.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
BSL_HASH_Iterator BSL_HASH_Erase(BSL_HASH_Hash *hash, uintptr_t key);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Delete all nodes in the hash table.
|
||||
* @par Description: Delete all nodes and reclaim the node memory. The hash table still exists, but there are no members
|
||||
* @attention Note: If the user data contains private resources, need to register the free hook function during creation
|
||||
* @param hash [IN] Handle of the hash table.
|
||||
* @retval none.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
void BSL_HASH_Clear(BSL_HASH_Hash *hash);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Delete the hash table.
|
||||
* @par Description: Delete the hash table. If a node exists in the table, delete the node first and reclaim the memory.
|
||||
* @attention Note: If the user data contains private resources, need to register the free hook function during creation
|
||||
* @param hash [IN] Handle of the hash table.
|
||||
* @retval none.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
void BSL_HASH_Destory(BSL_HASH_Hash *hash);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Obtain the iterator of the first node in the hash table.
|
||||
* @par Description: Obtains the iterator where the first node in the hash table is located.
|
||||
* @param hash [IN] Handle of the hash table.
|
||||
* @retval Iterator of the first node. If the hash is empty, #BSL_HASH_IterEnd() is returned.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
BSL_HASH_Iterator BSL_HASH_IterBegin(const BSL_HASH_Hash *hash);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Obtain the iterator reserved after the last node in the hash table.
|
||||
* @par Description: Obtain the iterator reserved after the last node in the hash table.
|
||||
* This node points to the last reserved hash bucket, which has no members.
|
||||
* @param hash [IN] Handle of the hash table.
|
||||
* @retval Iterator reserved after the last node.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
BSL_HASH_Iterator BSL_HASH_IterEnd(const BSL_HASH_Hash *hash);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Obtain the iterator of the next node in the hash table.
|
||||
* @par Description: Obtains the iterator of the next node in the hash table.
|
||||
* @param hash [IN] Handle of the hash table.
|
||||
* @param it [IN] Current iterator.
|
||||
* @retval Next node iterator. If the current node is the last iterator, #BSL_HASH_IterEnd() is returned.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
BSL_HASH_Iterator BSL_HASH_IterNext(const BSL_HASH_Hash *hash, BSL_HASH_Iterator it);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Obtain the key of the iterator.
|
||||
* @par Description: Obtains the current key of the iterator in the hash table.
|
||||
* @attention
|
||||
* 1. When the hash pointer is null or iterator it is equal to #BSL_HASH_IterEnd(), this function returns 0.
|
||||
* This function cannot distinguish whether the error code or user data,
|
||||
* 2. Before calling this function, ensure that hash is a valid pointer
|
||||
* and iterator it is not equal to #BSL_HASH_IterEnd().
|
||||
* @param hash [IN] Handle of the hash table.
|
||||
* @param it [IN] Current iterator.
|
||||
* @retval Key corresponding to the iterator. If iterator it equals #BSL_HASH_IterEnd(), 0 is returned.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
uintptr_t BSL_HASH_HashIterKey(const BSL_HASH_Hash *hash, BSL_HASH_Iterator it);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_hash
|
||||
* @brief Obtain the value of the iterator.
|
||||
* @par Description: Obtains the current value of the iterator in the hash table.
|
||||
* @attention
|
||||
* 1. When the hash pointer is null or it is equal to #BSL_HASH_IterEnd(), the interface returns 0.
|
||||
* This function cannot distinguish whether the error code or user data,
|
||||
* 2. Before calling this function, ensure that hash is a valid pointer
|
||||
* and iterator it is not equal to #BSL_HASH_IterEnd().
|
||||
* @param hash [IN] Handle of the hash table.
|
||||
* @param it [IN] Current iterator.
|
||||
* @retval Value corresponding to the iterator. If iterator it equals #BSL_HASH_IterEnd(), 0 is returned.
|
||||
* @par Dependency: None
|
||||
* @li bsl_hash.h: header file where this function's declaration is located.
|
||||
*/
|
||||
uintptr_t BSL_HASH_IterValue(const BSL_HASH_Hash *hash, BSL_HASH_Iterator it);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_BSL_HASH */
|
||||
|
||||
#endif // BSL_HASH_H
|
||||
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup bsl_list bidirectional linked list
|
||||
* @ingroup bsl
|
||||
*/
|
||||
|
||||
#ifndef BSL_HASH_LIST_H
|
||||
#define BSL_HASH_LIST_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_HASH
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief User data copy function prototype
|
||||
* @attention Note: The source buffer length needs to be obtained by the caller.
|
||||
* Because the data type and length are unknown, the hook function needs to be implemented by the service side.
|
||||
* @param ptr [IN] Pointer to user data
|
||||
* @param size [IN] User data copy length
|
||||
* @retval Destination buffer. NULL indicates failure.
|
||||
*/
|
||||
typedef void *(*ListDupFunc)(void *ptr, size_t size);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief User memory release function prototype
|
||||
* @par Description: resource release function prototype, which is generally used to release memory in batches.
|
||||
* The memory may contain private resources, which need to be released by users.
|
||||
* @param ptr [IN] Pointer to user data
|
||||
* @retval None
|
||||
*/
|
||||
typedef void (*ListFreeFunc)(void *ptr);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Match the function prototype.
|
||||
* @par Description: used to match the query.
|
||||
* @attention Note: Only the function prototype is defined here. Because the user query matching mechanism is unknown,
|
||||
* the hook function needs to be implemented by the service side.
|
||||
* @param node [IN] Algorithm structure node
|
||||
* @param data [IN] Key information
|
||||
* @retval true: Matching succeeded.
|
||||
* @retval false Matching failure
|
||||
*/
|
||||
typedef bool (*ListMatchFunc)(const void *node, uintptr_t data);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Compare function prototype
|
||||
* @par Description: Compare function prototype, which is used in sorting.
|
||||
* @attention Note: Only the comparison function prototype is defined here. The data type and length are unknown.
|
||||
* Therefore, the hook function needs to be implemented by the service side.
|
||||
* The current source code has a default comparison function. This function is not provided externally.
|
||||
* If the default comparison method is not specified, it will be invoked.
|
||||
* The comparison method is to convert the current data into a signed number for comparison,
|
||||
* that is, to process the case with negative numbers in ascending order.
|
||||
* If the data to be stored is of the unsigned integer type, The sorting result may not be expected at this time.
|
||||
* To compare data in this case, we need to customize the comparison function.
|
||||
* For example, for a BIGNUM A = uintptr_t(-1) and a BIGNUM B = 1ULL << 50, the current function considers A < B.
|
||||
* Actually, A is greater than B.
|
||||
* To sum up, the user should write the comparison function based on the data type
|
||||
* (including descending order or other comparison rules).
|
||||
*/
|
||||
typedef int32_t (*ListKeyCmpFunc)(uintptr_t key1, uintptr_t key2);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Hook for saving memory application and release.
|
||||
*/
|
||||
typedef struct {
|
||||
ListDupFunc dupFunc;
|
||||
ListFreeFunc freeFunc;
|
||||
} ListDupFreeFuncPair;
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* list header
|
||||
*/
|
||||
typedef struct BslListSt BSL_List;
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* Linked list iterator (node) definition
|
||||
*/
|
||||
typedef struct BslListNodeSt *BSL_ListIterator;
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Initialize the linked list.
|
||||
* @par Description: Initialize the linked list and
|
||||
* register the user data dup function and user data resource free function as required.
|
||||
* @attention
|
||||
* 1. If the data to be stored is of the integer type and the length <= sizeof(uintptr_t),
|
||||
* do not need to register dataFunc&dupFunc and assign it empty.
|
||||
* 2. If the user data is string or other customized complex data type
|
||||
* and the data life cycle is shorter than the node life cycle, user must register dataFunc->dupFunc for data copy.
|
||||
* @param list [IN] Linked list
|
||||
* @param dataFunc [IN] User data copy and release function pair. If dataFunc and dupFunc are not registered,
|
||||
* the default data type is integer.
|
||||
* @retval #BSL_SUCCESS 0 indicates that the linked list is successfully initialized.
|
||||
*/
|
||||
int32_t BSL_ListInit(BSL_List *list, const ListDupFreeFuncPair *dataFunc);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Clear the node in the linked list and delete all nodes.
|
||||
* @par Description: Clear the linked list node, delete all nodes, invoke the free function registered by the user
|
||||
* to release user resources, and return to the status after initialization of the linked list.
|
||||
* @param list [IN] Linked list
|
||||
* @retval #BSL_SUCCESS 0. The linked list is cleared successfully.
|
||||
*/
|
||||
int32_t BSL_ListClear(BSL_List *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Deinitialize the linked list.
|
||||
* @par Description: Deinitialize the linked list: Delete all nodes,
|
||||
* invoke the free function registered by the user to release user resources, and deregister the hook function.
|
||||
* @param list [IN] Linked list
|
||||
* @retval #BSL_SUCCESS 0. The linked list is successfully de-initialized.
|
||||
*/
|
||||
int32_t BSL_ListDeinit(BSL_List *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Check whether the linked list is empty.
|
||||
* @param list [IN] Linked list to be checked
|
||||
* @retval #true 1: The linked list is null or no data exists.
|
||||
* @retval #false 0: The linked list is not empty.
|
||||
* @li bsl_list.h: header file where the API declaration is located.
|
||||
*/
|
||||
bool BSL_ListIsEmpty(const BSL_List *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Obtain the number of nodes in the linked list.
|
||||
* @param list [IN] Linked list
|
||||
* @retval Number of linked list nodes
|
||||
* @li bsl_list.h: header file where the API declaration is located.
|
||||
*/
|
||||
size_t BSL_ListSize(const BSL_List *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Insert user data into the header of the linked list.
|
||||
* @param list [IN] Linked list
|
||||
* @param userData [IN] Data to be inserted or pointer to user private data
|
||||
* @param userDataSize [IN] Data copy length. If the user has not registered the dupFunc, this parameter is not used.
|
||||
* @retval #BSL_SUCCESS Data is successfully inserted.
|
||||
* @li bsl_list.h: header file where this function declaration is located.
|
||||
*/
|
||||
int32_t BSL_ListPushFront(BSL_List *list, uintptr_t userData, size_t userDataSize);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Insert user data to the end of the linked list.
|
||||
* @param list [IN] Linked list
|
||||
* @param userData [IN] Data to be inserted or pointer to user private data
|
||||
* @param userDataSize [IN] Data copy length. If the user has not registered the dupFunc, this parameter is not used.
|
||||
* @retval #BSL_SUCCESS Data is successfully inserted.
|
||||
* @li bsl_list.h: header file where this function declaration is located.
|
||||
*/
|
||||
int32_t BSL_ListPushBack(BSL_List *list, uintptr_t userData, size_t userDataSize);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief POP a node from the header of the linked list.
|
||||
* @par Description: Remove the head node from the linked list and release the node memory.
|
||||
* If the free function is registered during initialization, the hook function is called to release private resources.
|
||||
* If the linked list is empty, nothing will be done.
|
||||
* @param list [IN] Linked list
|
||||
* @retval #BSL_SUCCESS 0. The header is removed successfully.
|
||||
* @li bsl_list.h: header file where the API declaration is located.
|
||||
*/
|
||||
int32_t BSL_ListPopFront(BSL_List *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief POP a node from the end of the linked list.
|
||||
* @par Description: Remove the tail node from the linked list and release the node memory.
|
||||
* If the free function is registered during initialization, the hook function is called to release private resources.
|
||||
* If the linked list is empty, nothing will be done.
|
||||
* @param list [IN] Linked list
|
||||
* @retval #BSL_SUCCESS 0. The tail is removed successfully.
|
||||
* @li bsl_list.h: header file where the API declaration is located.
|
||||
*/
|
||||
int32_t BSL_ListPopBack(BSL_List *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Access the header node of the linked list and return the user data of the header node.
|
||||
* @par Description: Access the header node of the linked list and return the user data of the header node.
|
||||
* @attention Note: If the linked list is empty,
|
||||
* it cannot be distinguished whether the linked list is empty and the returned data is 0.
|
||||
* Therefore, before calling this function, we must check whether the linked list is empty.
|
||||
* @param list [IN] Linked list
|
||||
* @retval User data/pointer of the head node. If the linked list is empty, 0 is returned.
|
||||
* @li bsl_list.h: header file where this function declaration is located.
|
||||
*/
|
||||
uintptr_t BSL_ListFront(const BSL_List *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Access the tail node of the linked list and return the user data of the tail node.
|
||||
* @attention Note: If the linked list is empty,
|
||||
* it cannot be distinguished whether the linked list is empty and the returned data is 0.
|
||||
* Therefore, we must check whether the linked list is empty before calling this function.
|
||||
* @param list [IN] Linked list
|
||||
* @retval User data/pointer of the tail node. If the linked list is empty, 0 is returned.
|
||||
* @li bsl_list.h: header file where the API declaration is located.
|
||||
*/
|
||||
uintptr_t BSL_ListBack(const BSL_List *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Obtain the iterator of the header node of the linked list.
|
||||
* @param list [IN] Linked list
|
||||
* @retval Head node iterator of the linked list. If the linked list is empty, it points to the header.
|
||||
* @li bsl_list.h: header file where this function declaration is located.
|
||||
*/
|
||||
BSL_ListIterator BSL_ListIterBegin(const BSL_List *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Obtain the iterator of the next node of the tail.
|
||||
* @param list [IN] Linked list
|
||||
* @attention If the input list is NULL, NULL will be returned. Therefore, user need to use correct parameters.
|
||||
* @retval Next node iterator of the tail (pointing to the head of the linked list).
|
||||
* @li bsl_list.h: header file where the API declaration is located.
|
||||
*/
|
||||
BSL_ListIterator BSL_ListIterEnd(BSL_List *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Obtain the iterator of the previous node.
|
||||
* @param list [IN] Linked list
|
||||
* @param it [IN] Iterator
|
||||
* @attention If the input list is NULL or iterator it is not a valid part of the list, NULL is returned.
|
||||
* Therefore, user need to use the correct parameter.
|
||||
* @retval list is not empty, return the previous node iterator.
|
||||
* @retval list is NULL, and NULL is returned.
|
||||
* @li bsl_list.h: header file where the API declaration is located.
|
||||
*/
|
||||
BSL_ListIterator BSL_ListIterPrev(const BSL_List *list, const BSL_ListIterator it);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Obtain the iterator of the next node.
|
||||
* @param list [IN] Linked list
|
||||
* @param it [IN] Iterator
|
||||
* @attention If the input list is NULL or iterator it is not a valid part of the list, NULL is returned.
|
||||
* Therefore, user need to use the correct parameter.
|
||||
* @retval Returns the iterator of the next node if the value is not null.
|
||||
* @retval list is NULL, and NULL is returned.
|
||||
* @li bsl_list.h: header file where the API declaration is located.
|
||||
*/
|
||||
BSL_ListIterator BSL_ListIterNext(const BSL_List *list, const BSL_ListIterator it);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Insert data before the node pointed to by the specified iterator.
|
||||
* @param list [IN] Linked list
|
||||
* @param it [IN] Current iterator position
|
||||
* @param userData [IN] Data to be inserted or pointer to user private data
|
||||
* @param userDataSize [IN] Data copy length. If the user has not registered the dupFunc, this parameter is not used.
|
||||
* @retval #BSL_SUCCESS Data is successfully inserted.
|
||||
* @li bsl_list.h: header file where this function declaration is located.
|
||||
*/
|
||||
int32_t BSL_ListInsert(BSL_List *list, const BSL_ListIterator it, uintptr_t userData, size_t userDataSize);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Delete a specified node from the linked list and release the node memory.
|
||||
* @par Description: Delete the specified node from the linked list and release the node memory.
|
||||
* If the free function is registered during initialization,
|
||||
* the hook function is invoked to release private resources such as handles and pointers in user data
|
||||
* @attention If the input list is NULL or iterator it is not a valid part of the list, NULL is returned.
|
||||
* Therefore, user need to use the correct parameter.
|
||||
* @param list [IN] Linked list
|
||||
* @param it [IN] Iterator of the node to be deleted.
|
||||
* @retval Next node iterator of the deleted node. If the deleted node is the tail node,
|
||||
* the returned iterator points to the header of the linked list.
|
||||
* @li bsl_list.h: header file where this function declaration is located.
|
||||
*/
|
||||
BSL_ListIterator BSL_ListIterErase(BSL_List *list, BSL_ListIterator it);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Obtain user data.
|
||||
* @attention The caller must ensure the validity of the parameter. If the input parameter is invalid, 0 is returned.
|
||||
* The caller cannot distinguish whether the returned value 0 is normal data
|
||||
* or whether the returned value is 0 due to invalid parameters.
|
||||
* @param it [IN] Linked list iterator
|
||||
* @retval User data
|
||||
* @li bsl_list.h: header file where this function declaration is located.
|
||||
*/
|
||||
uintptr_t BSL_ListIterData(const BSL_ListIterator it);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Searches for the desired iterator, that is, the node pointer,
|
||||
* based on the user-defined iterator matching function.
|
||||
* @par Description: Searches for the desired iterator, that is, the node pointer,
|
||||
* based on the user-defined iterator matching function.
|
||||
* @attention
|
||||
* 1. Traversefrom the header and call the matching function for each node in turn
|
||||
* until the first matching node is found or the traversal ends at the tail of the linked list.
|
||||
* 2. The first input parameter address of the matching function hook entered by the user
|
||||
* is the userdata of each node to be searched. The input parameter type is uintptr_t.
|
||||
* 3. If the input list is NULL or the comparison function is NULL, NULL is returned.
|
||||
* Therefore, user need to use correct parameters.
|
||||
* @param list [IN] Linked list
|
||||
* @param iterCmpFunc [IN] Hook of match function.
|
||||
* @param data [IN] Data information
|
||||
* @retval not NULL Query succeeded, the matching node iterator is returned.
|
||||
* @retval NULL Query failed.
|
||||
* @li bsl_list.h: header file where this function declaration is located.
|
||||
*/
|
||||
BSL_ListIterator BSL_ListIterFind(BSL_List *list, ListKeyCmpFunc iterCmpFunc, uintptr_t data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_BSL_HASH */
|
||||
|
||||
#endif // BSL_HASH_LIST_H
|
||||
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup list_base Raw bidirectional linked list
|
||||
* @ingroup bsl
|
||||
*/
|
||||
|
||||
#ifndef LIST_BASE_H
|
||||
#define LIST_BASE_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_HASH
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "bsl_hash_list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* This struct is used to store the forward pointer and backward pointer of the node in the bidirectional linked list.
|
||||
* This linked list does not contain a substantial data area and is generally used to organize (concatenate) data nodes.
|
||||
*/
|
||||
struct ListTagRawListNode {
|
||||
struct ListTagRawListNode *next; /* points to the next node */
|
||||
struct ListTagRawListNode *prev; /* points to the previous node */
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* list node
|
||||
*/
|
||||
typedef struct ListTagRawListNode ListRawNode;
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* Linked list header, which cannot store data.
|
||||
*/
|
||||
typedef struct {
|
||||
ListRawNode head; /* list node */
|
||||
/* Node memory release function, which needs to release nodes and other private resources on node */
|
||||
ListFreeFunc freeFunc;
|
||||
} RawList;
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* Linked list header, which can apply for data memory and is used by external functions.
|
||||
*/
|
||||
struct BslListSt {
|
||||
RawList rawList; /* Linked list header */
|
||||
ListDupFreeFuncPair dataFunc; /* used to store data */
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* Bidirectional linked list node.
|
||||
* This structure is used to store the forward pointer and backward pointer of the nodes in the bidirectional list,
|
||||
* and a small amount of user data or pointers.
|
||||
*/
|
||||
struct BslListNodeSt {
|
||||
ListRawNode rawNode;
|
||||
uintptr_t userdata;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief Initialize the linked list.
|
||||
* @par Description: Initializes the list, registers the private resource release function in user data as required.
|
||||
* This function does not apply for resources.
|
||||
* @attention
|
||||
* 1: The linked list nodes in the crawlist module are encapsulated and memory is applied for by users.
|
||||
* The rawlist is only used to maintain the linked list, and its resources are released by users in freeFunc.
|
||||
* 2: When a user adds data, the parameter transferred to the rawlist is the ListRawNode node.
|
||||
* Therefore, the parameter transferred to the freeFunc by the rawlist is also the ListRawNode node.
|
||||
* @param list [IN] Linked list.
|
||||
* @param freeFunc [IN] User resource release function.
|
||||
* @retval #BSL_SUCCESS 0. The linked list is successfully initialized.
|
||||
*/
|
||||
int32_t ListRawInit(RawList *list, ListFreeFunc freeFunc);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief Clear the node in the linked list and delete all nodes.
|
||||
* @par Description: Clear the linked list node, delete all nodes,
|
||||
* invoke the free function registered by the user to release private resources,
|
||||
* and return to the status after initialization of the linked list.
|
||||
* @param list [IN] Linked list
|
||||
* @retval #BSL_SUCCESS 0. The linked list is cleared successfully.
|
||||
*/
|
||||
int32_t ListRawClear(RawList *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief Deinitialize the linked list.
|
||||
* @par Description: Deinitialize the linked list:
|
||||
* Delete all nodes, invoke the free function registered by the user to release private resources,
|
||||
* and deregister the hook function. But the list head is still there.
|
||||
* @param list [IN] Linked list
|
||||
* @retval #BSL_SUCCESS 0. The linked list is successfully deinitialized.
|
||||
*/
|
||||
int32_t ListRawDeinit(RawList *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief Check whether the linked list is empty.
|
||||
* @param list [IN] Linked list to be checked
|
||||
* @retval #true 1. The linked list is empty or has no data.
|
||||
* @retval #false 0. The linked list is not empty.
|
||||
* @li bsl_base.h: header file where the function declaration is located.
|
||||
*/
|
||||
bool ListRawEmpty(const RawList *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief Obtain the number of nodes in the linked list.
|
||||
* @param list [IN] Linked list
|
||||
* @retval Number of linked list nodes
|
||||
* @li bsl_base.h: header file where the function declaration is located.
|
||||
*/
|
||||
size_t ListRawSize(const RawList *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief Insert a node at the header of the linked list.
|
||||
* @param list [IN] Linked list
|
||||
* @param node [IN] Node to be inserted
|
||||
* @retval #BSL_SUCCESS 0. Inserted successfully in the header of the linked list.
|
||||
*/
|
||||
int32_t ListRawPushFront(RawList *list, ListRawNode *node);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief Insert a node at the end of the linked list.
|
||||
* @param list [IN] Linked list
|
||||
* @param node [IN] Node to be inserted
|
||||
* @retval #BSL_SUCCESS 0. Inserted successfully in the tail of the linked list.
|
||||
*/
|
||||
int32_t ListRawPushBack(RawList *list, ListRawNode *node);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief Insert a node before a specified node.
|
||||
* @param curNode [IN] Specified node
|
||||
* @param newNode [IN] Node to be inserted
|
||||
* @retval #BSL_SUCCESS 0 indicates that the linked list is inserted successfully.
|
||||
*/
|
||||
int32_t ListIRawnsert(const ListRawNode *curNode, ListRawNode *newNode);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief POP a node from the header of the linked list.
|
||||
* @par Description: Removes the head node from the linked list.
|
||||
* If the free function is registered during initialization, the hook function is also called to release user resources.
|
||||
* If the linked list is empty, nothing will be done.
|
||||
* @param list [IN] Linked list
|
||||
* @retval #BSL_SUCCESS 0. The header of the linked list is popped successfully.
|
||||
*/
|
||||
int32_t ListRawPopFront(RawList *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief POP a node from the end of the linked list.
|
||||
* @par Description: Remove the tail node from the linked list.
|
||||
* If the free function is registered during initialization, the hook function is also called to release user resources.
|
||||
* If the linked list is empty, nothing will be done.
|
||||
* @param list [IN] Linked list
|
||||
* @retval #BSL_SUCCESS 0. The tail of the linked list is popped successfully.
|
||||
*/
|
||||
int32_t ListRawPopBack(RawList *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief Delete a specified node from the linked list.
|
||||
* @par Description:
|
||||
* 1. If the list is NULL and the node is in the linked list, only the node is removed from the linked list.
|
||||
* 2. If the list is not null and the node is in the linked list, the node is removed from the linked list.
|
||||
* If the free function is registered during initialization, the hook function is invoked to release user resources.
|
||||
* @param list [IN] Linked list
|
||||
* @param node [IN] Node to be deleted
|
||||
* @retval #BSL_SUCCESS 0. The linked list is deleted successfully.
|
||||
* @li bsl_base.h: header file where the function declaration is located.
|
||||
*/
|
||||
int32_t ListRawRemove(RawList *list, ListRawNode *node);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief Return the head node pointer.
|
||||
* @par Description: It is used only to access the head node and will not delete the node.
|
||||
* If the linked list is NULL, NULL is returned.
|
||||
* @param list [IN] Linked list
|
||||
* @attention If the input parameter is incorrect, NULL is returned. The user needs to use the correct parameter.
|
||||
* @retval not NULL Pointer to the head node.
|
||||
* @retval NULL The linked list is NULL.
|
||||
* @li bsl_base.h: header file where the function declaration is located.
|
||||
*/
|
||||
ListRawNode *ListRawFront(const RawList *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief Return the tail node pointer.
|
||||
* @par Description: It is used only to access the tail node and will not delete the tail node.
|
||||
* If the linked list is NULL, NULL is returned.
|
||||
* @param list [IN] Linked list
|
||||
* @attention If the input parameter is incorrect, NULL is returned. The user needs to use the correct parameter.
|
||||
* @retval not NULL Pointer to the tail node.
|
||||
* @retval NULL The linked list is NULL.
|
||||
* @li bsl_base.h: header file where the function declaration is located.
|
||||
*/
|
||||
ListRawNode *ListRawBack(const RawList *list);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief Obtain the previous node of the current node.
|
||||
* @par Description: Obtains the pointer of the previous node of the current node.
|
||||
* If the current node is the head node, NULL is returned.
|
||||
* @param list [IN] Linked list
|
||||
* @param node [IN] Current node
|
||||
* @attention If the input parameter is incorrect, NULL is returned. The user needs to use the correct parameter.
|
||||
* @retval Non-NULL Previous node of the current node
|
||||
* @retval NULL The previous node of the head node is empty.
|
||||
* @li bsl_base.h: header file where the function declaration is located.
|
||||
*/
|
||||
ListRawNode *ListRawGetPrev(const RawList *list, const ListRawNode *node);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief Obtain the next node of the current node.
|
||||
* @par Description: Obtains the pointer to the next node of the current node.
|
||||
* If the current node is the tail node, NULL is returned.
|
||||
* @param list [IN] Linked list
|
||||
* @param node [IN] Current node
|
||||
* @attention If the input parameter is incorrect, NULL is returned. The user needs to use the correct parameter.
|
||||
* @retval: non-NULL node next to the current node
|
||||
* @retval: NULL The next node of the tail node is null.
|
||||
* @li bsl_base.h: header file where the function declaration is located.
|
||||
*/
|
||||
ListRawNode *ListRawGetNext(const RawList *list, const ListRawNode *node);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief Searches for the desired node based on the node matching function defined by the user.
|
||||
* @par Description: Searches for the desired node based on the node matching function defined by the user.
|
||||
* @attention
|
||||
* 1. Traverse from the header of the linked list and call the matching function for each node in turn
|
||||
* until the first matching node is found or the traversal ends at the tail of the linked list.
|
||||
* 2. Hook of the matching function entered by the user.
|
||||
* Its first input parameter address is the value of each node to be searched.
|
||||
* The input parameter type is ListRawNode *.
|
||||
* 3. For the implementation in the matching hook,
|
||||
* needs to be offset to the user structure information according to the node address before matching and comparison.
|
||||
* 4. If the input parameter is incorrect, NULL is returned. The user needs to use the correct parameter.
|
||||
* @param list [IN] Linked list
|
||||
* @param nodeMatchFunc [IN] hook of match function.
|
||||
* @param data [IN] critical information
|
||||
* @retval non-NULL The query is successful, the node pointer is returned.
|
||||
* @retval NULL Query failed. No matching node is found.
|
||||
* @li bsl_base.h: header file where the function declaration is located.
|
||||
*/
|
||||
ListRawNode *ListRawFindNode(const RawList *list, ListMatchFunc nodeMatchFunc, uintptr_t data);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_base
|
||||
* @brief This API obtains the start address of the structure through a member variable of the structure.
|
||||
* @par Description:
|
||||
* This API obtains the start address of the structure through a member variable of the structure.
|
||||
* This API is a special macro, and the input parameters depend on the implementation of the macro.
|
||||
* @attention
|
||||
* @param ptr [IN] The address of a member on a node. The value range is Data Type.
|
||||
* @param type [IN] The node type structure to which the transferred member belongs. The value range is Data Type.
|
||||
* @param member [IN] The name of a member variable in the structure. The value range is Data Type.
|
||||
* @retval Address of the same structure as the input parameter type.
|
||||
* @see none.
|
||||
*/
|
||||
#define BSL_CONTAINER_OF(ptr, type, member) \
|
||||
((type *)((uintptr_t)(ptr) - (uintptr_t)(&(((type *)0)->member))))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_BSL_HASH */
|
||||
|
||||
#endif // LIST_BASE_H
|
||||
@@ -0,0 +1,664 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_HASH
|
||||
|
||||
#include "securec.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "list_base.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_err_internal.h"
|
||||
#include "hash_local.h"
|
||||
#include "bsl_hash.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define BSL_CSTL_HASH_OPTION3 3
|
||||
#define BSL_CSTL_HASH_OPTION2 2
|
||||
#define BSL_CSTL_HASH_OPTION1 1
|
||||
|
||||
struct BSL_HASH_TagNode {
|
||||
ListRawNode node; /**< Linked list node */
|
||||
uintptr_t key; /**< Key or address for storing the key */
|
||||
uintptr_t value; /**< value or address for storing the value */
|
||||
};
|
||||
|
||||
typedef struct BSL_HASH_TagNode BSL_HASH_Node;
|
||||
|
||||
struct BSL_HASH_Info {
|
||||
ListDupFreeFuncPair keyFunc; /**< key Copy and release function pair */
|
||||
ListDupFreeFuncPair valueFunc; /**< value Copy and release function pair */
|
||||
BSL_HASH_MatchFunc matchFunc; /**< matching function */
|
||||
BSL_HASH_CodeCalcFunc hashFunc; /**< hash function */
|
||||
uint32_t bucketSize; /**< hash table size */
|
||||
uint32_t hashCount; /**< number of entries in the hash table */
|
||||
RawList listArray[0]; /**< linked list control block array*/
|
||||
};
|
||||
|
||||
/* murmurhash algorithm */
|
||||
/* define constants */
|
||||
#define HASH_VC1 0xCC9E2D51
|
||||
#define HASH_VC2 0x1B873593
|
||||
#define HASH_HC1 0xE6546B64
|
||||
#define HASH_HC2 0x85EBCA6B
|
||||
#define HASH_HC3 0xC2B2AE35
|
||||
#define HASH_HC4 5
|
||||
|
||||
#define CHAR_BIT 8
|
||||
#define CHAR_FOR_PER_LOOP 4
|
||||
#define HASH_V_ROTATE 15
|
||||
#define HASH_H_ROTATE 13
|
||||
#define SYS_BUS_WIDTH sizeof(uint32_t)
|
||||
#define HASH_SEED 0x3B9ACA07 /* large prime 1000000007. The seed can be random or specified. */
|
||||
|
||||
enum BSL_CstlByte {
|
||||
ONE_BYTE = 1,
|
||||
TWO_BYTE = 2,
|
||||
};
|
||||
|
||||
enum BSL_CstlShiftBit { SHIFT8 = 8, SHIFT13 = 13, SHIFT16 = 16, SHIFT24 = 24 };
|
||||
|
||||
static uint32_t BSL_HASH_Rotate(uint32_t v, uint32_t offset)
|
||||
{
|
||||
return ((v << offset) | (v >> (SYS_BUS_WIDTH * CHAR_BIT - offset)));
|
||||
}
|
||||
|
||||
static uint32_t BSL_HASH_MixV(uint32_t v)
|
||||
{
|
||||
uint32_t res = v;
|
||||
res = res * HASH_VC1;
|
||||
res = BSL_HASH_Rotate(res, HASH_V_ROTATE);
|
||||
res = res * HASH_VC2;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static uint32_t BSL_HASH_MixH(uint32_t h, uint32_t v)
|
||||
{
|
||||
uint32_t res = h;
|
||||
|
||||
res ^= v;
|
||||
res = BSL_HASH_Rotate(res, HASH_H_ROTATE);
|
||||
res = res * HASH_HC4 + HASH_HC1;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
uint32_t BSL_HASH_CodeCalc(void *key, uint32_t keySize)
|
||||
{
|
||||
uint8_t *tmpKey = (uint8_t *)key;
|
||||
uint32_t i = 0;
|
||||
uint32_t v;
|
||||
uint32_t h = HASH_SEED;
|
||||
uint8_t c0, c1, c2, c3;
|
||||
uint32_t tmpLen = keySize - keySize % CHAR_FOR_PER_LOOP;
|
||||
|
||||
while ((i + CHAR_FOR_PER_LOOP) <= tmpLen) {
|
||||
c0 = tmpKey[i++];
|
||||
c1 = tmpKey[i++];
|
||||
c2 = tmpKey[i++];
|
||||
c3 = tmpKey[i++];
|
||||
|
||||
v = (uint32_t)c0 | ((uint32_t)c1 << SHIFT8) | ((uint32_t)c2 << SHIFT16) | ((uint32_t)c3 << SHIFT24);
|
||||
v = BSL_HASH_MixV(v);
|
||||
h = BSL_HASH_MixH(h, v);
|
||||
}
|
||||
|
||||
v = 0;
|
||||
|
||||
switch (keySize & BSL_CSTL_HASH_OPTION3) {
|
||||
case BSL_CSTL_HASH_OPTION3:
|
||||
v ^= ((uint32_t)tmpKey[i + TWO_BYTE] << SHIFT16);
|
||||
/* (keySize % 4) is equals 3, fallthrough, other branches are the same. */
|
||||
/* fall-through */
|
||||
case BSL_CSTL_HASH_OPTION2:
|
||||
v ^= ((uint32_t)tmpKey[i + ONE_BYTE] << SHIFT8);
|
||||
/* fall-through */
|
||||
case BSL_CSTL_HASH_OPTION1:
|
||||
v ^= tmpKey[i];
|
||||
v = BSL_HASH_MixV(v);
|
||||
h ^= v;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
h ^= h >> SHIFT16;
|
||||
|
||||
h *= HASH_HC2;
|
||||
h ^= h >> SHIFT13;
|
||||
h *= HASH_HC3;
|
||||
h ^= h >> SHIFT16;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
/* internal function definition */
|
||||
static void BSL_HASH_HookRegister(BSL_HASH_Hash *hash, BSL_HASH_CodeCalcFunc hashFunc,
|
||||
BSL_HASH_MatchFunc matchFunc, ListDupFreeFuncPair *keyFunc, ListDupFreeFuncPair *valueFunc)
|
||||
{
|
||||
ListDupFreeFuncPair *hashKeyFunc = &hash->keyFunc;
|
||||
ListDupFreeFuncPair *hashValueFunc = &hash->valueFunc;
|
||||
|
||||
if (hashFunc == NULL) {
|
||||
hash->hashFunc = BSL_HASH_CodeCalcInt;
|
||||
} else {
|
||||
hash->hashFunc = hashFunc;
|
||||
}
|
||||
|
||||
if (matchFunc == NULL) {
|
||||
hash->matchFunc = BSL_HASH_MatchInt;
|
||||
} else {
|
||||
hash->matchFunc = matchFunc;
|
||||
}
|
||||
|
||||
if (keyFunc == NULL) {
|
||||
hashKeyFunc->dupFunc = NULL;
|
||||
hashKeyFunc->freeFunc = NULL;
|
||||
} else {
|
||||
hashKeyFunc->dupFunc = keyFunc->dupFunc;
|
||||
hashKeyFunc->freeFunc = keyFunc->freeFunc;
|
||||
}
|
||||
|
||||
if (valueFunc == NULL) {
|
||||
hashValueFunc->dupFunc = NULL;
|
||||
hashValueFunc->freeFunc = NULL;
|
||||
} else {
|
||||
hashValueFunc->dupFunc = valueFunc->dupFunc;
|
||||
hashValueFunc->freeFunc = valueFunc->freeFunc;
|
||||
}
|
||||
}
|
||||
|
||||
static inline BSL_HASH_Iterator BSL_HASH_IterEndGet(const BSL_HASH_Hash *hash)
|
||||
{
|
||||
return (BSL_HASH_Iterator)(uintptr_t)(&hash->listArray[hash->bucketSize].head);
|
||||
}
|
||||
|
||||
static BSL_HASH_Node *BSL_HASH_NodeCreate(
|
||||
const BSL_HASH_Hash *hash, uintptr_t key, uint32_t keySize, uintptr_t value, uint32_t valueSize)
|
||||
{
|
||||
uintptr_t tmpKey;
|
||||
uintptr_t tmpValue;
|
||||
BSL_HASH_Node *hashNode = NULL;
|
||||
void *tmpPtr = NULL;
|
||||
|
||||
hashNode = (BSL_HASH_Node *)BSL_SAL_Malloc(sizeof(BSL_HASH_Node));
|
||||
if (hashNode == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hash->keyFunc.dupFunc != NULL) {
|
||||
tmpPtr = hash->keyFunc.dupFunc((void *)key, keySize);
|
||||
tmpKey = (uintptr_t)tmpPtr;
|
||||
if (tmpKey == (uintptr_t)NULL) {
|
||||
BSL_SAL_FREE(hashNode);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
tmpKey = key;
|
||||
}
|
||||
|
||||
if (hash->valueFunc.dupFunc != NULL) {
|
||||
tmpPtr = hash->valueFunc.dupFunc((void *)value, valueSize);
|
||||
tmpValue = (uintptr_t)tmpPtr;
|
||||
if (tmpValue == (uintptr_t)NULL) {
|
||||
if (hash->keyFunc.freeFunc != NULL) {
|
||||
hash->keyFunc.freeFunc((void *)tmpKey);
|
||||
}
|
||||
|
||||
BSL_SAL_FREE(hashNode);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
tmpValue = value;
|
||||
}
|
||||
|
||||
hashNode->key = tmpKey;
|
||||
hashNode->value = tmpValue;
|
||||
|
||||
return hashNode;
|
||||
}
|
||||
|
||||
static BSL_HASH_Node *BSL_HASH_FindNode(const RawList *list, uintptr_t key, BSL_HASH_MatchFunc matchFunc)
|
||||
{
|
||||
BSL_HASH_Node *hashNode = NULL;
|
||||
ListRawNode *rawListNode = NULL;
|
||||
|
||||
for (rawListNode = ListRawFront(list); rawListNode != NULL; rawListNode = ListRawGetNext(list, rawListNode)) {
|
||||
hashNode = BSL_CONTAINER_OF(rawListNode, BSL_HASH_Node, node);
|
||||
if (matchFunc(hashNode->key, key)) {
|
||||
return hashNode;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BSL_HASH_Iterator BSL_HASH_Front(const BSL_HASH_Hash *hash)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
const RawList *list = NULL;
|
||||
ListRawNode *rawListNode = NULL;
|
||||
|
||||
while (i < hash->bucketSize) {
|
||||
list = &hash->listArray[i];
|
||||
rawListNode = ListRawFront(list);
|
||||
if (rawListNode != NULL) {
|
||||
return BSL_CONTAINER_OF(rawListNode, BSL_HASH_Node, node);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return BSL_HASH_IterEndGet(hash);
|
||||
}
|
||||
|
||||
static BSL_HASH_Iterator BSL_HASH_Next(const BSL_HASH_Hash *hash, BSL_HASH_Iterator hashNode)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t hashCode;
|
||||
const RawList *list = NULL;
|
||||
ListRawNode *rawListNode = NULL;
|
||||
|
||||
hashCode = hash->hashFunc(hashNode->key, hash->bucketSize);
|
||||
if (hashCode >= hash->bucketSize) {
|
||||
return BSL_HASH_IterEndGet(hash);
|
||||
}
|
||||
|
||||
list = hash->listArray + hashCode;
|
||||
rawListNode = ListRawGetNext(list, &hashNode->node);
|
||||
if (rawListNode != NULL) {
|
||||
return BSL_CONTAINER_OF(rawListNode, BSL_HASH_Node, node);
|
||||
}
|
||||
|
||||
for (i = hashCode + 1; i < hash->bucketSize; ++i) {
|
||||
list = &hash->listArray[i];
|
||||
rawListNode = ListRawFront(list);
|
||||
if (rawListNode != NULL) {
|
||||
return BSL_CONTAINER_OF(rawListNode, BSL_HASH_Node, node);
|
||||
}
|
||||
}
|
||||
|
||||
return BSL_HASH_IterEndGet(hash);
|
||||
}
|
||||
|
||||
static void BSL_HASH_NodeFree(BSL_HASH_Hash *hash, BSL_HASH_Node *node)
|
||||
{
|
||||
ListFreeFunc keyFreeFunc = hash->keyFunc.freeFunc;
|
||||
ListFreeFunc valueFreeFunc = hash->valueFunc.freeFunc;
|
||||
|
||||
if (keyFreeFunc != NULL) {
|
||||
keyFreeFunc((void *)node->key);
|
||||
}
|
||||
|
||||
if (valueFreeFunc != NULL) {
|
||||
valueFreeFunc((void *)node->value);
|
||||
}
|
||||
|
||||
BSL_SAL_FREE(node);
|
||||
}
|
||||
|
||||
uint32_t BSL_HASH_CodeCalcInt(uintptr_t key, uint32_t bktSize)
|
||||
{
|
||||
uint32_t hashCode = BSL_HASH_CodeCalc(&key, sizeof(key));
|
||||
|
||||
return hashCode % bktSize;
|
||||
}
|
||||
|
||||
bool BSL_HASH_MatchInt(uintptr_t key1, uintptr_t key2)
|
||||
{
|
||||
return key1 == key2;
|
||||
}
|
||||
|
||||
uint32_t BSL_HASH_CodeCalcStr(uintptr_t key, uint32_t bktSize)
|
||||
{
|
||||
char *tmpKey = (char *)key;
|
||||
uint32_t hashCode = BSL_HASH_CodeCalc(tmpKey, (uint32_t)strlen(tmpKey));
|
||||
|
||||
return hashCode % bktSize;
|
||||
}
|
||||
|
||||
bool BSL_HASH_MatchStr(uintptr_t key1, uintptr_t key2)
|
||||
{
|
||||
char *tkey1 = (char *)key1;
|
||||
char *tkey2 = (char *)key2;
|
||||
|
||||
if (strcmp(tkey1, tkey2) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BSL_HASH_Hash *BSL_HASH_Create(uint32_t bktSize, BSL_HASH_CodeCalcFunc hashFunc, BSL_HASH_MatchFunc matchFunc,
|
||||
ListDupFreeFuncPair *keyFunc, ListDupFreeFuncPair *valueFunc)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t size;
|
||||
BSL_HASH_Hash *hash = NULL;
|
||||
RawList *listAddr = NULL;
|
||||
if (bktSize == 0U) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = (bktSize + 1) * sizeof(RawList);
|
||||
if (IsMultiOverflow((bktSize + 1), sizeof(RawList)) || IsAddOverflow(size, sizeof(BSL_HASH_Hash))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size += sizeof(BSL_HASH_Hash);
|
||||
hash = (BSL_HASH_Hash *)BSL_SAL_Malloc(size);
|
||||
if (hash == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)memset_s(hash, size, 0, size);
|
||||
hash->bucketSize = bktSize;
|
||||
BSL_HASH_HookRegister(hash, hashFunc, matchFunc, keyFunc, valueFunc);
|
||||
|
||||
listAddr = hash->listArray;
|
||||
for (i = 0; i <= bktSize; ++i) {
|
||||
ListRawInit(listAddr + i, NULL);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static int32_t BSL_HASH_InsertNode(
|
||||
BSL_HASH_Hash *hash, RawList *rawList, const BSL_CstlUserData *inputKey, const BSL_CstlUserData *inputValue)
|
||||
{
|
||||
BSL_HASH_Node *hashNode = BSL_HASH_NodeCreate(
|
||||
hash, inputKey->inputData, inputKey->dataSize, inputValue->inputData, inputValue->dataSize);
|
||||
if (hashNode == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
|
||||
ListRawPushBack(rawList, &hashNode->node);
|
||||
hash->hashCount++;
|
||||
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BSL_HASH_UpdateNode(const BSL_HASH_Hash *hash, BSL_HASH_Node *node, uintptr_t value, uint32_t valueSize)
|
||||
{
|
||||
uintptr_t tmpValue;
|
||||
void *tmpPtr = NULL;
|
||||
|
||||
if (hash->valueFunc.dupFunc != NULL) {
|
||||
tmpPtr = hash->valueFunc.dupFunc((void *)value, valueSize);
|
||||
tmpValue = (uintptr_t)tmpPtr;
|
||||
if (tmpValue == (uintptr_t)NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
|
||||
if (hash->valueFunc.freeFunc != NULL) {
|
||||
hash->valueFunc.freeFunc((void *)node->value);
|
||||
}
|
||||
} else {
|
||||
tmpValue = value;
|
||||
}
|
||||
|
||||
node->value = tmpValue;
|
||||
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int32_t BSL_HASH_CodeCheck(const BSL_HASH_Hash *hash, uintptr_t key, uint32_t *hashCode)
|
||||
{
|
||||
if (hash == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
|
||||
*hashCode = hash->hashFunc(key, hash->bucketSize);
|
||||
if (*hashCode >= hash->bucketSize) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_HASH_Insert(BSL_HASH_Hash *hash, uintptr_t key, uint32_t keySize, uintptr_t value, uint32_t valueSize)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t hashCode;
|
||||
BSL_HASH_Node *hashNode = NULL;
|
||||
RawList *rawList = NULL;
|
||||
BSL_CstlUserData inputKey;
|
||||
BSL_CstlUserData inputValue;
|
||||
|
||||
ret = BSL_HASH_CodeCheck(hash, key, &hashCode);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
|
||||
rawList = &hash->listArray[hashCode];
|
||||
hashNode = BSL_HASH_FindNode(rawList, key, hash->matchFunc);
|
||||
if (hashNode != NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
|
||||
inputKey.inputData = key;
|
||||
inputKey.dataSize = keySize;
|
||||
inputValue.inputData = value;
|
||||
inputValue.dataSize = valueSize;
|
||||
|
||||
return BSL_HASH_InsertNode(hash, rawList, &inputKey, &inputValue);
|
||||
}
|
||||
|
||||
int32_t BSL_HASH_Put(BSL_HASH_Hash *hash, uintptr_t key, uint32_t keySize, uintptr_t value, uint32_t valueSize)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t hashCode;
|
||||
RawList *rawList = NULL;
|
||||
BSL_HASH_Node *hashNode = NULL;
|
||||
BSL_CstlUserData inputValue;
|
||||
BSL_CstlUserData inputKey;
|
||||
|
||||
ret = BSL_HASH_CodeCheck(hash, key, &hashCode);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
|
||||
rawList = &hash->listArray[hashCode];
|
||||
hashNode = BSL_HASH_FindNode(rawList, key, hash->matchFunc);
|
||||
if (hashNode != NULL) {
|
||||
return BSL_HASH_UpdateNode(hash, hashNode, value, valueSize);
|
||||
}
|
||||
|
||||
inputKey.inputData = key;
|
||||
inputKey.dataSize = keySize;
|
||||
inputValue.inputData = value;
|
||||
inputValue.dataSize = valueSize;
|
||||
|
||||
return BSL_HASH_InsertNode(hash, rawList, &inputKey, &inputValue);
|
||||
}
|
||||
|
||||
int32_t BSL_HASH_At(const BSL_HASH_Hash *hash, uintptr_t key, uintptr_t *value)
|
||||
{
|
||||
BSL_HASH_Node *hashNode = BSL_HASH_Find(hash, key);
|
||||
|
||||
if (hashNode == BSL_HASH_IterEndGet(hash)) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
|
||||
*value = hashNode->value;
|
||||
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
BSL_HASH_Iterator BSL_HASH_Find(const BSL_HASH_Hash *hash, uintptr_t key)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t hashCode;
|
||||
BSL_HASH_Node *hashNode = NULL;
|
||||
|
||||
ret = BSL_HASH_CodeCheck(hash, key, &hashCode);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return hash == NULL ? NULL : BSL_HASH_IterEndGet(hash);
|
||||
}
|
||||
|
||||
hashNode = BSL_HASH_FindNode(&hash->listArray[hashCode], key, hash->matchFunc);
|
||||
if (hashNode == NULL) {
|
||||
return BSL_HASH_IterEndGet(hash);
|
||||
}
|
||||
|
||||
return hashNode;
|
||||
}
|
||||
|
||||
bool BSL_HASH_Empty(const BSL_HASH_Hash *hash)
|
||||
{
|
||||
if ((hash == NULL) || (hash->hashCount == 0U)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t BSL_HASH_Size(const BSL_HASH_Hash *hash)
|
||||
{
|
||||
if (hash == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hash->hashCount;
|
||||
}
|
||||
|
||||
BSL_HASH_Iterator BSL_HASH_Erase(BSL_HASH_Hash *hash, uintptr_t key)
|
||||
{
|
||||
uint32_t hashCode;
|
||||
BSL_HASH_Node *hashNode = NULL;
|
||||
BSL_HASH_Node *nextHashNode = NULL;
|
||||
BSL_HASH_MatchFunc matchFunc = NULL;
|
||||
BSL_HASH_CodeCalcFunc hashFunc = NULL;
|
||||
|
||||
if (hash == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hashFunc = hash->hashFunc;
|
||||
hashCode = hashFunc(key, hash->bucketSize);
|
||||
if (hashCode >= hash->bucketSize) {
|
||||
return BSL_HASH_IterEndGet(hash);
|
||||
}
|
||||
|
||||
matchFunc = hash->matchFunc;
|
||||
hashNode = BSL_HASH_FindNode(&hash->listArray[hashCode], key, matchFunc);
|
||||
if (hashNode == NULL) {
|
||||
return BSL_HASH_IterEndGet(hash);
|
||||
}
|
||||
|
||||
nextHashNode = BSL_HASH_Next(hash, hashNode);
|
||||
ListRawRemove(&hash->listArray[hashCode], &hashNode->node);
|
||||
BSL_HASH_NodeFree(hash, hashNode);
|
||||
--hash->hashCount;
|
||||
|
||||
return nextHashNode;
|
||||
}
|
||||
|
||||
void BSL_HASH_Clear(BSL_HASH_Hash *hash)
|
||||
{
|
||||
uint32_t i;
|
||||
RawList *list = NULL;
|
||||
BSL_HASH_Node *hashNode = NULL;
|
||||
ListRawNode *rawListNode = NULL;
|
||||
|
||||
if (hash == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < hash->bucketSize; ++i) {
|
||||
list = &hash->listArray[i];
|
||||
while (!ListRawEmpty(list)) {
|
||||
rawListNode = ListRawFront(list);
|
||||
hashNode = BSL_CONTAINER_OF(rawListNode, BSL_HASH_Node, node);
|
||||
ListRawRemove(list, rawListNode);
|
||||
BSL_HASH_NodeFree(hash, hashNode);
|
||||
}
|
||||
}
|
||||
|
||||
hash->hashCount = 0;
|
||||
}
|
||||
|
||||
void BSL_HASH_Destory(BSL_HASH_Hash *hash)
|
||||
{
|
||||
if (hash == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
BSL_HASH_Clear(hash);
|
||||
BSL_SAL_FREE(hash);
|
||||
}
|
||||
|
||||
BSL_HASH_Iterator BSL_HASH_IterBegin(const BSL_HASH_Hash *hash)
|
||||
{
|
||||
if (hash == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return BSL_HASH_Front(hash);
|
||||
}
|
||||
|
||||
BSL_HASH_Iterator BSL_HASH_IterEnd(const BSL_HASH_Hash *hash)
|
||||
{
|
||||
if (hash == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return BSL_HASH_IterEndGet(hash);
|
||||
}
|
||||
|
||||
BSL_HASH_Iterator BSL_HASH_IterNext(const BSL_HASH_Hash *hash, BSL_HASH_Iterator it)
|
||||
{
|
||||
if ((hash == NULL) || (it == BSL_HASH_IterEnd(hash))) {
|
||||
return BSL_HASH_IterEnd(hash);
|
||||
}
|
||||
|
||||
return BSL_HASH_Next(hash, it);
|
||||
}
|
||||
|
||||
uintptr_t BSL_HASH_HashIterKey(const BSL_HASH_Hash *hash, BSL_HASH_Iterator it)
|
||||
{
|
||||
if (it == NULL || it == BSL_HASH_IterEnd(hash)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return it->key;
|
||||
}
|
||||
|
||||
uintptr_t BSL_HASH_IterValue(const BSL_HASH_Hash *hash, BSL_HASH_Iterator it)
|
||||
{
|
||||
if (it == NULL || it == BSL_HASH_IterEnd(hash)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return it->value;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HITLS_BSL_HASH */
|
||||
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_HASH
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "list_base.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_hash_list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct BslListNodeSt ListNode;
|
||||
|
||||
int32_t BSL_ListInit(BSL_List *list, const ListDupFreeFuncPair *dataFunc)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
|
||||
if (list != NULL) {
|
||||
ret = ListRawInit(&list->rawList, NULL);
|
||||
|
||||
if (dataFunc == NULL) {
|
||||
list->dataFunc.dupFunc = NULL;
|
||||
list->dataFunc.freeFunc = NULL;
|
||||
} else {
|
||||
list->dataFunc.dupFunc = dataFunc->dupFunc;
|
||||
list->dataFunc.freeFunc = dataFunc->freeFunc;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t ListRemoveNode(BSL_List *list, ListNode *node)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if (list->dataFunc.freeFunc != NULL) {
|
||||
(list->dataFunc.freeFunc((void *)(node->userdata)));
|
||||
}
|
||||
|
||||
ret = ListRawRemove(&list->rawList, &node->rawNode);
|
||||
if (ret == BSL_SUCCESS) {
|
||||
BSL_SAL_FREE(node);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_ListClear(BSL_List *list)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
ListNode *node = NULL;
|
||||
const RawList *rawList = NULL;
|
||||
const ListRawNode *head = NULL;
|
||||
|
||||
if (list != NULL) {
|
||||
rawList = &list->rawList;
|
||||
head = &rawList->head;
|
||||
while (!ListRawEmpty(rawList)) {
|
||||
node = BSL_CONTAINER_OF(head->next, ListNode, rawNode);
|
||||
ret = ListRemoveNode(list, node);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_ListDeinit(BSL_List *list)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
|
||||
if (list != NULL) {
|
||||
ret = BSL_ListClear(list);
|
||||
list->dataFunc.dupFunc = NULL;
|
||||
list->dataFunc.freeFunc = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t ListWriteUserdata(const BSL_List *list, ListNode *node, uintptr_t userData, size_t userDataSize)
|
||||
{
|
||||
int32_t ret;
|
||||
const void *copyBuff = NULL;
|
||||
|
||||
if (list->dataFunc.dupFunc == NULL) {
|
||||
node->userdata = userData;
|
||||
ret = BSL_SUCCESS;
|
||||
} else {
|
||||
copyBuff = list->dataFunc.dupFunc((void *)userData, userDataSize);
|
||||
if (copyBuff == NULL) {
|
||||
ret = BSL_INTERNAL_EXCEPTION;
|
||||
} else {
|
||||
node->userdata = (uintptr_t)copyBuff;
|
||||
ret = BSL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ListNode *NewNodeCreateByUserData(const BSL_List *list, uintptr_t userData, size_t userDataSize)
|
||||
{
|
||||
ListNode *node = NULL;
|
||||
|
||||
if (list != NULL) {
|
||||
node = (ListNode *)BSL_SAL_Malloc(sizeof(ListNode));
|
||||
if (node != NULL) {
|
||||
if (ListWriteUserdata(list, node, userData, userDataSize) != BSL_SUCCESS) {
|
||||
BSL_SAL_FREE(node);
|
||||
node = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
int32_t BSL_ListPushFront(BSL_List *list, uintptr_t userData, size_t userDataSize)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
ListNode *node;
|
||||
|
||||
node = NewNodeCreateByUserData(list, userData, userDataSize);
|
||||
if (node != NULL) {
|
||||
ret = ListRawPushFront(&list->rawList, &node->rawNode);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_ListPushBack(BSL_List *list, uintptr_t userData, size_t userDataSize)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
ListNode *node = NULL;
|
||||
|
||||
if (list != NULL) {
|
||||
node = NewNodeCreateByUserData(list, userData, userDataSize);
|
||||
if (node != NULL) {
|
||||
ret = ListRawPushBack(&list->rawList, &node->rawNode);
|
||||
} else {
|
||||
ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_ListInsert(BSL_List *list, const BSL_ListIterator it, uintptr_t userData, size_t userDataSize)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
ListNode *node = NULL;
|
||||
|
||||
if ((list != NULL) && (it != NULL)) {
|
||||
node = NewNodeCreateByUserData(list, userData, userDataSize);
|
||||
if (node != NULL) {
|
||||
ret = ListIRawnsert(&it->rawNode, &node->rawNode);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
if (list->dataFunc.freeFunc != NULL) {
|
||||
list->dataFunc.freeFunc((void *)(node->userdata));
|
||||
}
|
||||
BSL_SAL_FREE(node);
|
||||
}
|
||||
} else {
|
||||
ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool BSL_ListIsEmpty(const BSL_List *list)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
if (list != NULL) {
|
||||
ret = ListRawEmpty(&list->rawList);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_ListPopFront(BSL_List *list)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
ListNode *firstNode = NULL;
|
||||
|
||||
if (!BSL_ListIsEmpty(list)) {
|
||||
firstNode = BSL_CONTAINER_OF(list->rawList.head.next, ListNode, rawNode);
|
||||
ret = ListRemoveNode(list, firstNode);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_ListPopBack(BSL_List *list)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
ListNode *lastNode = NULL;
|
||||
|
||||
if (!BSL_ListIsEmpty(list)) {
|
||||
lastNode = BSL_CONTAINER_OF(list->rawList.head.prev, ListNode, rawNode);
|
||||
ret = ListRemoveNode(list, lastNode);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BSL_ListIterator BSL_ListIterErase(BSL_List *list, BSL_ListIterator it)
|
||||
{
|
||||
int32_t ret = BSL_INTERNAL_EXCEPTION;
|
||||
BSL_ListIterator retIt;
|
||||
|
||||
if (BSL_ListIsEmpty(list) || (it == NULL) || (it == (BSL_ListIterator)(&list->rawList.head))) {
|
||||
retIt = NULL;
|
||||
} else {
|
||||
retIt = BSL_CONTAINER_OF(it->rawNode.next, ListNode, rawNode);
|
||||
ret = ListRemoveNode(list, it);
|
||||
}
|
||||
|
||||
if (ret != BSL_SUCCESS) {
|
||||
retIt = NULL;
|
||||
}
|
||||
|
||||
return retIt;
|
||||
}
|
||||
|
||||
uintptr_t BSL_ListFront(const BSL_List *list)
|
||||
{
|
||||
uintptr_t frontData = 0;
|
||||
const ListNode *node = NULL;
|
||||
|
||||
if (!BSL_ListIsEmpty(list)) {
|
||||
node = BSL_CONTAINER_OF(list->rawList.head.next, ListNode, rawNode);
|
||||
frontData = node->userdata;
|
||||
}
|
||||
|
||||
return frontData;
|
||||
}
|
||||
|
||||
uintptr_t BSL_ListBack(const BSL_List *list)
|
||||
{
|
||||
uintptr_t backData = 0;
|
||||
const ListNode *node = NULL;
|
||||
|
||||
if (!BSL_ListIsEmpty(list)) {
|
||||
node = BSL_CONTAINER_OF(list->rawList.head.prev, ListNode, rawNode);
|
||||
backData = node->userdata;
|
||||
}
|
||||
|
||||
return backData;
|
||||
}
|
||||
|
||||
BSL_ListIterator BSL_ListIterBegin(const BSL_List *list)
|
||||
{
|
||||
BSL_ListIterator beginIterator = NULL;
|
||||
|
||||
if (list != NULL) {
|
||||
beginIterator = BSL_CONTAINER_OF(list->rawList.head.next, ListNode, rawNode);
|
||||
}
|
||||
|
||||
return beginIterator;
|
||||
}
|
||||
|
||||
BSL_ListIterator BSL_ListIterEnd(BSL_List *list)
|
||||
{
|
||||
BSL_ListIterator endIterator = NULL;
|
||||
|
||||
if (list != NULL) {
|
||||
endIterator = (BSL_ListIterator)(&list->rawList.head);
|
||||
}
|
||||
|
||||
return endIterator;
|
||||
}
|
||||
|
||||
size_t BSL_ListSize(const BSL_List *list)
|
||||
{
|
||||
size_t size = 0;
|
||||
|
||||
if (list != NULL) {
|
||||
size = ListRawSize(&list->rawList);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
BSL_ListIterator BSL_ListIterPrev(const BSL_List *list, const BSL_ListIterator it)
|
||||
{
|
||||
BSL_ListIterator prev = NULL;
|
||||
|
||||
if ((!BSL_ListIsEmpty(list)) && (it != NULL)) {
|
||||
prev = BSL_CONTAINER_OF(it->rawNode.prev, ListNode, rawNode);
|
||||
}
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
BSL_ListIterator BSL_ListIterNext(const BSL_List *list, const BSL_ListIterator it)
|
||||
{
|
||||
BSL_ListIterator next = NULL;
|
||||
|
||||
if ((!BSL_ListIsEmpty(list)) && (it != NULL)) {
|
||||
next = BSL_CONTAINER_OF(it->rawNode.next, ListNode, rawNode);
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
uintptr_t BSL_ListIterData(const BSL_ListIterator it)
|
||||
{
|
||||
uintptr_t data = 0;
|
||||
|
||||
if (it != NULL) {
|
||||
data = it->userdata;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/* Linked list node search function. The type of the first parameter of iterCmpFunc is userdata of each iterator. */
|
||||
BSL_ListIterator BSL_ListIterFind(BSL_List *list, ListKeyCmpFunc iterCmpFunc, uintptr_t data)
|
||||
{
|
||||
BSL_ListIterator it = NULL, headIt = NULL;
|
||||
BSL_ListIterator ans = NULL;
|
||||
|
||||
if ((list != NULL) && (iterCmpFunc != NULL)) {
|
||||
headIt = (BSL_ListIterator)BSL_CONTAINER_OF(&list->rawList.head, ListNode, rawNode);
|
||||
it = BSL_CONTAINER_OF(list->rawList.head.next, ListNode, rawNode);
|
||||
while (it != headIt) {
|
||||
if (iterCmpFunc(it->userdata, data) == 0) {
|
||||
ans = it;
|
||||
break;
|
||||
}
|
||||
|
||||
it = BSL_CONTAINER_OF(it->rawNode.next, ListNode, rawNode);
|
||||
}
|
||||
}
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_BSL_HASH */
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_HASH
|
||||
|
||||
#include "hash_local.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool IsMultiOverflow(uint32_t x, uint32_t y)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if ((x > 0) && (y > 0)) {
|
||||
ret = ((SIZE_MAX / x) < y) ? true : false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool IsAddOverflow(uint32_t x, uint32_t y)
|
||||
{
|
||||
return ((x + y) < x);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_BSL_HASH */
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef HASH_LOCAL_H
|
||||
#define HASH_LOCAL_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_HASH
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cpluscplus */
|
||||
|
||||
typedef struct {
|
||||
uintptr_t inputData; /* Actual data input by the user. */
|
||||
uint32_t dataSize; /* Actual input size */
|
||||
} BSL_CstlUserData;
|
||||
|
||||
/* Check whether overflow occurs when two numbers are multiplied in the current system. */
|
||||
bool IsMultiOverflow(uint32_t x, uint32_t y);
|
||||
|
||||
/* Check whether the sum of the two numbers overflows in the current system. */
|
||||
bool IsAddOverflow(uint32_t x, uint32_t y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_BSL_HASH */
|
||||
|
||||
#endif /* HASH_LOCAL_H */
|
||||
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_HASH
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "bsl_errno.h"
|
||||
#include "list_base.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* internal function definition */
|
||||
static inline bool ListRawNodeInList(const ListRawNode *node)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if ((node->next != NULL) && (node->prev != NULL) &&
|
||||
((const ListRawNode *)(node->next->prev) == node) &&
|
||||
((const ListRawNode *)(node->prev->next) == node)) {
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool IsListRawEmptyCheck(const RawList *list)
|
||||
{
|
||||
return (&list->head)->next == &list->head;
|
||||
}
|
||||
|
||||
static inline void ListRawAddAfterNode(ListRawNode *node, ListRawNode *where)
|
||||
{
|
||||
node->next = (where)->next;
|
||||
node->prev = (where);
|
||||
where->next = node;
|
||||
node->next->prev = node;
|
||||
}
|
||||
|
||||
static inline void ListRawAddBeforeNode(ListRawNode *node, const ListRawNode *where)
|
||||
{
|
||||
ListRawAddAfterNode(node, where->prev);
|
||||
}
|
||||
|
||||
static inline bool IsListRawFirstNode(const RawList *list, const ListRawNode *node)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if ((const ListRawNode *)list->head.next == node) {
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool IsListRawLastNode(const RawList *list, const ListRawNode *node)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if ((const ListRawNode *)list->head.prev == node) {
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Deleting the list node, internal function, input parameter validation is not required. */
|
||||
static void ListRawRemoveNode(const RawList *list, ListRawNode *node)
|
||||
{
|
||||
node->prev->next = node->next;
|
||||
node->next->prev = node->prev;
|
||||
|
||||
if (list->freeFunc != NULL) {
|
||||
list->freeFunc((void *)node);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ListRawInit(RawList *list, ListFreeFunc freeFunc)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
|
||||
if (list != NULL) {
|
||||
list->head.next = &list->head;
|
||||
list->head.prev = &list->head;
|
||||
list->freeFunc = freeFunc;
|
||||
ret = BSL_SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t ListRawClear(RawList *list)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
|
||||
if (list != NULL) {
|
||||
while (!IsListRawEmptyCheck(list)) {
|
||||
ListRawRemoveNode(list, (ListRawNode *)list->head.next);
|
||||
}
|
||||
|
||||
ret = BSL_SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t ListRawDeinit(RawList *list)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
|
||||
if (list != NULL) {
|
||||
ret = ListRawClear(list);
|
||||
list->freeFunc = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ListRawEmpty(const RawList *list)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
if (list != NULL) {
|
||||
ret = IsListRawEmptyCheck(list);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline size_t ListRawSizeInner(const RawList *list)
|
||||
{
|
||||
size_t size = 0;
|
||||
const ListRawNode *node = NULL, *head = NULL;
|
||||
|
||||
head = &list->head;
|
||||
for (node = head->next; node != head; node = node->next) {
|
||||
size++;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t ListRawSize(const RawList *list)
|
||||
{
|
||||
size_t size = 0;
|
||||
|
||||
if ((list != NULL) && !IsListRawEmptyCheck(list)) {
|
||||
size = ListRawSizeInner(list);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t ListRawPushFront(RawList *list, ListRawNode *node)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
|
||||
if ((list != NULL) && (node != NULL)) {
|
||||
ListRawAddAfterNode(node, &(list->head));
|
||||
ret = BSL_SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t ListRawPushBack(RawList *list, ListRawNode *node)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
|
||||
if ((list != NULL) && (node != NULL)) {
|
||||
ListRawAddBeforeNode(node, &(list->head));
|
||||
ret = BSL_SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t ListIRawnsert(const ListRawNode *curNode, ListRawNode *newNode)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
|
||||
if ((curNode != NULL) && (newNode != NULL) && (ListRawNodeInList(curNode))) {
|
||||
ListRawAddBeforeNode(newNode, curNode);
|
||||
ret = BSL_SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t ListRawPopFront(RawList *list)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
ListRawNode *firstNode = NULL;
|
||||
|
||||
if ((list != NULL) && (!IsListRawEmptyCheck(list))) {
|
||||
firstNode = list->head.next;
|
||||
ListRawRemoveNode(list, firstNode);
|
||||
ret = BSL_SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t ListRawPopBack(RawList *list)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
ListRawNode *lastNode = NULL;
|
||||
|
||||
if (list != NULL) {
|
||||
if (!IsListRawEmptyCheck(list)) {
|
||||
lastNode = list->head.prev;
|
||||
ListRawRemoveNode(list, lastNode);
|
||||
ret = BSL_SUCCESS;
|
||||
} else {
|
||||
ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ListRawRemoveInner(RawList *list, ListRawNode *node)
|
||||
{
|
||||
node->prev->next = node->next;
|
||||
node->next->prev = node->prev;
|
||||
|
||||
if ((list != NULL) && !IsListRawEmptyCheck(list) && (list->freeFunc != NULL)) {
|
||||
list->freeFunc((void *)node);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ListRawRemove(RawList *list, ListRawNode *node)
|
||||
{
|
||||
int32_t ret = (int32_t)BSL_INTERNAL_EXCEPTION;
|
||||
|
||||
if ((node != NULL) && (ListRawNodeInList(node))) {
|
||||
ListRawRemoveInner(list, node);
|
||||
ret = BSL_SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ListRawNode *ListRawFront(const RawList *list)
|
||||
{
|
||||
ListRawNode *front = NULL;
|
||||
|
||||
if ((list != NULL) && (!IsListRawEmptyCheck(list))) {
|
||||
front = list->head.next;
|
||||
}
|
||||
|
||||
return front;
|
||||
}
|
||||
|
||||
ListRawNode *ListRawBack(const RawList *list)
|
||||
{
|
||||
ListRawNode *back = NULL;
|
||||
|
||||
if ((list != NULL) && (!IsListRawEmptyCheck(list))) {
|
||||
back = list->head.prev;
|
||||
}
|
||||
|
||||
return back;
|
||||
}
|
||||
|
||||
ListRawNode *ListRawGetPrev(const RawList *list, const ListRawNode *node)
|
||||
{
|
||||
ListRawNode *prev = NULL;
|
||||
|
||||
if ((list == NULL) || (node == NULL) ||
|
||||
(IsListRawEmptyCheck(list)) || (IsListRawFirstNode(list, node)) || (!ListRawNodeInList(node))) {
|
||||
prev = NULL;
|
||||
} else {
|
||||
prev = node->prev;
|
||||
}
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
ListRawNode *ListRawGetNext(const RawList *list, const ListRawNode *node)
|
||||
{
|
||||
ListRawNode *next = NULL;
|
||||
|
||||
if ((list == NULL) || (node == NULL) ||
|
||||
(IsListRawEmptyCheck(list)) || (IsListRawLastNode(list, node)) || (!ListRawNodeInList(node))) {
|
||||
next = NULL;
|
||||
} else {
|
||||
next = node->next;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
/* Linked list node search function. The type of the first parameter of nodeMatchFunc must be (ListRawNode *) */
|
||||
ListRawNode *ListRawFindNode(const RawList *list, ListMatchFunc nodeMatchFunc, uintptr_t data)
|
||||
{
|
||||
ListRawNode *ans = NULL;
|
||||
ListRawNode *node = NULL;
|
||||
const ListRawNode *head = NULL;
|
||||
|
||||
if ((list != NULL) && (nodeMatchFunc != NULL)) {
|
||||
head = (const ListRawNode *)(&list->head);
|
||||
node = head->next;
|
||||
while ((const ListRawNode *)node != head) {
|
||||
if (nodeMatchFunc((void *)node, data)) {
|
||||
ans = node;
|
||||
break;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_BSL_HASH */
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#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,
|
||||
BINLOG_ID05061, BINLOG_ID05062, BINLOG_ID05063, BINLOG_ID05064, BINLOG_ID05065,
|
||||
BINLOG_ID05066, BINLOG_ID05067, BINLOG_ID05068
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef BSL_BYTES_H
|
||||
#define BSL_BYTES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief convert uint8_t byte stream to uint16_t data
|
||||
*
|
||||
* @attention data cannot be empty
|
||||
*
|
||||
* @param data [IN] uint8_t byte stream
|
||||
*
|
||||
* @return uint16_t converted data
|
||||
*/
|
||||
static inline uint16_t BSL_ByteToUint16(const uint8_t *data)
|
||||
{
|
||||
/** Byte 0 is shifted by 8 bits to the left, and byte 1 remains unchanged. uint16_t is obtained after OR */
|
||||
return ((uint16_t)data[0] << 8) | ((uint16_t)data[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief convert uint16_t data to uint8_t byte stream
|
||||
*
|
||||
* @attention data cannot be empty
|
||||
*
|
||||
* @param num [IN] data to be converted
|
||||
* @param data [OUT] converted data
|
||||
*/
|
||||
static inline void BSL_Uint16ToByte(uint16_t num, uint8_t *data)
|
||||
{
|
||||
/** convert to byte stream */
|
||||
data[0] = (uint8_t)(num >> 8); // data is shifted rightwards by 8 bits and put in byte 0
|
||||
data[1] = (uint8_t)(num & 0xffu); // data AND 0xffu, put in byte 1
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief convert uint8_t byte stream to uint24_t data
|
||||
*
|
||||
* @attention data cannot be empty
|
||||
*
|
||||
* @param data [IN] uint8_t byte stream
|
||||
*
|
||||
* @return uint24_t, converted data
|
||||
*/
|
||||
static inline uint32_t BSL_ByteToUint24(const uint8_t *data)
|
||||
{
|
||||
/** Byte 0 is shifted left by 16 bits, byte 1 is shifted left by 8 bits, and byte 2 remains unchanged,
|
||||
uint24_t is obtained after the OR operation. */
|
||||
return ((uint32_t)data[0] << 16) | ((uint32_t)data[1] << 8) | ((uint32_t)data[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief convert uint24_t data to uint8_t byte stream
|
||||
*
|
||||
* @attention data cannot be empty
|
||||
*
|
||||
* @param num [IN] data to be converted
|
||||
* @param data [OUT] converted data
|
||||
*/
|
||||
static inline void BSL_Uint24ToByte(uint32_t num, uint8_t *data)
|
||||
{
|
||||
/** convert to byte stream */
|
||||
data[0] = (uint8_t)(num >> 16); // data is shifted rightwards by 16 bits and put in byte 0
|
||||
data[1] = (uint8_t)(num >> 8); // data is shifted rightwards by 8 bits and placed in byte 1
|
||||
data[2] = (uint8_t)(num & 0xffu); // data AND 0xffu, put in byte 2
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief convert uint8_t byte stream to uint32_t data
|
||||
*
|
||||
* @attention data cannot be empty
|
||||
*
|
||||
* @param data [IN] uint8_t byte stream
|
||||
*
|
||||
* @return uint32_t, converted data
|
||||
*/
|
||||
static inline uint32_t BSL_ByteToUint32(const uint8_t *data)
|
||||
{
|
||||
/** Byte 0 is shifted leftward by 24 bits, byte 1 is shifted leftward by 16 bits,
|
||||
byte 2 is shifted leftward by 8 bits, and byte 3 remains unchanged, uint32_t is obtained after OR operation. */
|
||||
return ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) | ((uint32_t)data[2] << 8) | ((uint32_t)data[3]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief convert uint8_t byte stream to uint48_t data
|
||||
*
|
||||
* @attention data cannot be empty
|
||||
*
|
||||
* @param data [IN] uint8_t byte stream
|
||||
*
|
||||
* @return uint48_t, converted data
|
||||
*/
|
||||
static inline uint64_t BSL_ByteToUint48(const uint8_t *data)
|
||||
{
|
||||
/** Byte 0 is shifted leftward by 40 bits, byte 1 is shifted leftward by 32 bits,
|
||||
byte 2 is shifted leftward by 24 bits, byte 3 is shifted leftward by 16 bits,
|
||||
byte 4 is shifted leftward by 8 bits, and byte 5 remains unchanged, uint48_t is obtained after OR operation. */
|
||||
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 convert uint48_t data to uint8_t byte stream
|
||||
*
|
||||
* @attention data cannot be empty
|
||||
*
|
||||
* @param num [IN] data to be converted
|
||||
* @param data [OUT] converted data
|
||||
*/
|
||||
static inline void BSL_Uint48ToByte(uint64_t num, uint8_t *data)
|
||||
{
|
||||
/** convert to byte stream */
|
||||
data[0] = (uint8_t)(num >> 40); // data is shifted rightwards by 40 bits and put in byte 0
|
||||
data[1] = (uint8_t)(num >> 32); // data is shifted rightwards by 32 bits and put in byte 1
|
||||
data[2] = (uint8_t)(num >> 24); // data is shifted rightwards by 24 bits and put in byte 2
|
||||
data[3] = (uint8_t)(num >> 16); // data is shifted rightwards by 16 bits and put in byte 3
|
||||
data[4] = (uint8_t)(num >> 8); // data is shifted rightwards by 8 bits and put in byte 4
|
||||
data[5] = (uint8_t)(num & 0xffu); // data AND 0xffu, put in byte 5
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief convert uint8_t byte stream to uint64_t data
|
||||
*
|
||||
* @attention data cannot be empty
|
||||
*
|
||||
* @param data [IN] uint8_t byte stream
|
||||
*
|
||||
* @return uint32_t, converted data
|
||||
*/
|
||||
static inline uint64_t BSL_ByteToUint64(const uint8_t *data)
|
||||
{
|
||||
/** Byte 0 is shifted leftward by 56 bits, byte 1 is shifted leftward by 48 bits,
|
||||
byte 2 is shifted leftward by 40 bits, byte 3 is shifted leftward by 32 bits,
|
||||
byte 4 is shifted leftward by 24 bits, byte 5 is shifted leftward by 16 bits,
|
||||
byte 6 is shifted leftward by 8 bits, and byte 7 remains unchanged, uint64_t is obtained after OR operation. */
|
||||
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 convert uint32_t data to uint8_t byte stream
|
||||
*
|
||||
* @attention data cannot be empty
|
||||
*
|
||||
* @param num [IN] data to be converted
|
||||
* @param data [OUT] converted data
|
||||
*/
|
||||
static inline void BSL_Uint32ToByte(uint32_t num, uint8_t *data)
|
||||
{
|
||||
/** convert to byte stream */
|
||||
data[0] = (uint8_t)(num >> 24); // data is shifted rightwards by 24 bits and put in byte 0
|
||||
data[1] = (uint8_t)(num >> 16); // data is shifted rightwards by 16 bits and put in byte 1
|
||||
data[2] = (uint8_t)(num >> 8); // data is shifted rightwards by 8 bits and put in byte 2
|
||||
data[3] = (uint8_t)(num & 0xffu); // data AND 0xffu, put in byte 3
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief convert uint64_t data to uint8_t byte stream
|
||||
*
|
||||
* @attention data cannot be empty
|
||||
*
|
||||
* @param num [IN] data to be converted
|
||||
* @param data [OUT] converted data
|
||||
*/
|
||||
static inline void BSL_Uint64ToByte(uint64_t num, uint8_t *data)
|
||||
{
|
||||
/** convert to byte stream */
|
||||
data[0] = (uint8_t)(num >> 56); // data is shifted rightwards by 56 bits and put in byte 0
|
||||
data[1] = (uint8_t)(num >> 48); // data is shifted rightwards by 48 bits and put in byte 1
|
||||
data[2] = (uint8_t)(num >> 40); // data is shifted rightwards by 40 bits and put in byte 2
|
||||
data[3] = (uint8_t)(num >> 32); // data is shifted rightwards by 32 bits and put in byte 3
|
||||
data[4] = (uint8_t)(num >> 24); // data is shifted rightwards by 24 bits and put in byte 4
|
||||
data[5] = (uint8_t)(num >> 16); // data is shifted rightwards by 16 bits and put in byte 5
|
||||
data[6] = (uint8_t)(num >> 8); // data is shifted rightwards by 8 bits and put in byte 6
|
||||
data[7] = (uint8_t)(num & 0xffu); // data AND 0xffu, put in byte 7
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif // BSL_BYTES_H
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef BSL_MODULE_LIST_H
|
||||
#define BSL_MODULE_LIST_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This structure is used to store the forward and backward pointers of nodes in the bidirectional linked list.
|
||||
* This linked list does not contain substantial data areas and is generally used to organize (concatenate) data nodes.
|
||||
*/
|
||||
typedef struct ListHeadSt {
|
||||
struct ListHeadSt *next, *prev;
|
||||
} ListHead;
|
||||
|
||||
/**
|
||||
* @brief initialize the linked list when the linked list is reused
|
||||
*
|
||||
* @param head [IN] The address of the head node of the list
|
||||
*/
|
||||
#define LIST_INIT(head) (head)->next = (head)->prev = (head)
|
||||
|
||||
/**
|
||||
* @brief Insert the 'item' node after the 'where' node.
|
||||
Before the change: where->A->B. After the change: where->item->A->B
|
||||
*
|
||||
* @param where [IN] The address where the item will be inserted after
|
||||
* @param item [IN] Address of the node(item) to be inserted
|
||||
*/
|
||||
#define LIST_ADD_AFTER(where, item) do { \
|
||||
(item)->next = (where)->next; \
|
||||
(item)->prev = (where); \
|
||||
(where)->next = (item); \
|
||||
(item)->next->prev = (item); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief Insert the 'item' node before the 'where' node.
|
||||
* Before change: A->where->B. After change: A->item->where->B
|
||||
*
|
||||
* @param where [IN] The address where the item will be inserted before
|
||||
* @param item [IN] Address of the node to be inserted
|
||||
*/
|
||||
#define LIST_ADD_BEFORE(where, item) LIST_ADD_AFTER((where)->prev, (item))
|
||||
|
||||
/**
|
||||
* @brief Delete the node 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 Check whether a list is empty
|
||||
*
|
||||
* @param head [IN] The address of the list to be checked.
|
||||
*/
|
||||
#define LIST_IS_EMPTY(head) ((head)->next == (head))
|
||||
|
||||
/**
|
||||
* @brief Travel through a list safety
|
||||
*
|
||||
* @param head [IN] Linked list to be traversed (The head of a list)
|
||||
* @param temp [IN] Point to the current node to safely delete the current node
|
||||
* @param item [IN] A temporary list node 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 Find the start address of the struct(large node) where the node is located
|
||||
* through a node (small node) in the linked list.
|
||||
*
|
||||
* @param item [IN] The address of a list item
|
||||
* @param type [IN] Type of the large node that contains the linked list node.
|
||||
* @param member [IN] Name of the list node in the structure
|
||||
*
|
||||
* Note:
|
||||
* Each struct variable forms a large node (including data and list nodes).
|
||||
* The large node is connected through the list(small node).
|
||||
* --------- --------- --------- -- ----
|
||||
* | pre |<---| pre |<---| pre | |==>small node |
|
||||
* | next |--->| next |--->| next | | |
|
||||
* --------- --------- --------- -- | ===> Large node
|
||||
* | data1 | | data1 | | data1 | |
|
||||
* | data2 | | data2 | | data2 | |
|
||||
* --------- --------- --------- ----
|
||||
* The reason why the list is not directly used as the big node is that
|
||||
* the list (ListHead type) has only the head and tail pointers and does not contain the data area.
|
||||
* In this way, the list can be used for mounting any data and is universal.
|
||||
*/
|
||||
#define LIST_ENTRY(item, type, member) \
|
||||
((type *)((uintptr_t)(char *)(item) - (uintptr_t)(&((type *)0)->member)))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // BSL_MODULE_LIST_H
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_INIT
|
||||
|
||||
#include "bsl_err.h"
|
||||
#include "bsl_errno.h"
|
||||
|
||||
int32_t BSL_GLOBAL_Init(void)
|
||||
{
|
||||
return BSL_ERR_Init();
|
||||
}
|
||||
|
||||
int32_t BSL_GLOBAL_DeInit(void)
|
||||
{
|
||||
BSL_ERR_DeInit();
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* HITLS_BSL_INIT */
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef BSL_LIST_INTERNAL_H
|
||||
#define BSL_LIST_INTERNAL_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_LIST
|
||||
|
||||
#include "bsl_list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int32_t (*QSORT_COMP_FN_TYPE)(const void *, const void *);
|
||||
|
||||
/* Sort the list in ascending order of content */
|
||||
int32_t BSL_ListSortInternal(BslList *pList, int32_t((*cmp)(const void *, const void *)));
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief To return the data of the node at the given index in the list, starting at 0.
|
||||
*
|
||||
* @param[IN] ulIndex The index in the list.
|
||||
* @param[IN] pstListNode The list node.
|
||||
* @param[IN] pstList The list.
|
||||
*
|
||||
* @retval void* The element which was found. [void *]
|
||||
* @retval void* If none found. [NULL]
|
||||
*/
|
||||
void *BSL_LIST_GetIndexNodeEx(uint32_t ulIndex, const BslListNode *pstListNode, const BslList *pstList);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief This function searches a list based on the comparator function supplied (3rd param).
|
||||
* The second param is given to the comparator as its second param and each data item on the
|
||||
* list is given as its first param while searching. The comparator must return 0 to indicate a match.
|
||||
*
|
||||
* The Search callback function should return -2(SEC_INT_ERROR) if search should not be continued anymore.
|
||||
*
|
||||
* @param[IN] pList The list.
|
||||
* @param[IN] pSearchFor The element to be searched.
|
||||
* @param[IN] pSearcher The pointer to the comparison function of data.
|
||||
* @param[OUT] pstErr Error codes for internal error. [-2/0]
|
||||
*
|
||||
* @retval Void* The element which was found [Void*]
|
||||
* @retval Void* If none found [NULL]
|
||||
*/
|
||||
void *BSL_LIST_SearchEx(BslList *pList, const void *pSearchFor, BSL_LIST_PFUNC_CMP pSearcher);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief This creates a new node before/after/At end /begin of the current node. If the list was already empty,
|
||||
* the node will be added as the only node.The current pointer is changed to point to the newly added node in the list.
|
||||
* If the current pointer is NULL then this operation fails.
|
||||
*
|
||||
* @param[IN] pList The list.
|
||||
* @param[IN] pData The element to be added.
|
||||
* @param[IN] enPosition Whether the element is to be added before/after the list
|
||||
*
|
||||
* @retval uint32_t, The error code
|
||||
* BSL_LIST_INVALID_LIST_CURRENT: If current pointer is NULL
|
||||
* BSL_LIST_DATA_NOT_AVAILABLE: If data pointer is NULL
|
||||
* BSL_MALLOC_FAIL: If failure to allocate memory for new node
|
||||
* BSL_SUCCESS: If successful
|
||||
*/
|
||||
uint32_t BSL_LIST_AddElementInt(BslList *pList, void *pData, BslListPosition enPosition);
|
||||
|
||||
#define CURR_LIST_NODE(al) ((al)->curr)
|
||||
|
||||
#define SET_CURR_LIST_NODE(al, listNode) ((al)->curr = (listNode))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HITLS_BSL_LIST */
|
||||
|
||||
#endif // BSL_LIST_INTERNAL_H
|
||||
@@ -0,0 +1,569 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_LIST
|
||||
|
||||
#include "bsl_list_internal.h"
|
||||
#include "bsl_err_internal.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "securec.h"
|
||||
#include "bsl_list.h"
|
||||
|
||||
#define MAX_LIST_ELEM_CNT_DEFAULT 10000000
|
||||
|
||||
/* this global var limits the maximum node number of a list */
|
||||
static int32_t g_maxListCount = MAX_LIST_ELEM_CNT_DEFAULT;
|
||||
|
||||
static uint32_t BslListAddAfterCurr(BslList *pList, void *pData)
|
||||
{
|
||||
BslListNode *newNode = NULL;
|
||||
|
||||
/* check for missing argument */
|
||||
if (pList == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
|
||||
/* check if current is null */
|
||||
if (pList->curr == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_LIST_INVALID_LIST_CURRENT);
|
||||
return BSL_LIST_INVALID_LIST_CURRENT;
|
||||
}
|
||||
|
||||
/* allocate memory for new node */
|
||||
newNode = BSL_SAL_Calloc(1, sizeof(BslListNode));
|
||||
if (newNode == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
|
||||
return BSL_MALLOC_FAIL;
|
||||
}
|
||||
|
||||
newNode->data = pData;
|
||||
|
||||
/* add new node after current */
|
||||
newNode->next = pList->curr->next;
|
||||
newNode->prev = pList->curr;
|
||||
if ((pList->curr->next) != NULL) {
|
||||
pList->curr->next->prev = newNode;
|
||||
} else {
|
||||
pList->last = newNode;
|
||||
}
|
||||
|
||||
pList->curr->next = newNode;
|
||||
|
||||
pList->curr = newNode;
|
||||
pList->count++;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t BslListInsertBeforeCurr(BslList *pList, void *pData)
|
||||
{
|
||||
BslListNode *pNewNode = NULL;
|
||||
|
||||
/* check if current is null */
|
||||
/* check for missing argument */
|
||||
if (pList == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
|
||||
if (pList->curr == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_LIST_INVALID_LIST_CURRENT);
|
||||
return BSL_LIST_INVALID_LIST_CURRENT;
|
||||
}
|
||||
|
||||
/* allocate memory for new node */
|
||||
pNewNode = BSL_SAL_Calloc(1, sizeof(BslListNode));
|
||||
if (pNewNode == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
|
||||
return BSL_MALLOC_FAIL;
|
||||
}
|
||||
|
||||
pNewNode->data = pData;
|
||||
|
||||
/* add new node before current */
|
||||
pNewNode->next = pList->curr;
|
||||
pNewNode->prev = pList->curr->prev;
|
||||
if ((pList->curr->prev) != NULL) {
|
||||
pList->curr->prev->next = pNewNode;
|
||||
} else {
|
||||
pList->first = pNewNode;
|
||||
}
|
||||
|
||||
pList->curr->prev = pNewNode;
|
||||
|
||||
pList->curr = pNewNode;
|
||||
pList->count++;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t BSL_LIST_AddElementInt(BslList *pList, void *pData, BslListPosition enPosition)
|
||||
{
|
||||
BslListNode *pNewNode = NULL;
|
||||
|
||||
if (pList->count >= g_maxListCount) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_LIST_FULL);
|
||||
return BSL_LIST_FULL;
|
||||
}
|
||||
|
||||
if (pList->curr == NULL) {
|
||||
if (pList->first == NULL) {
|
||||
/* allocate memory for new node */
|
||||
pNewNode = BSL_SAL_Calloc(1, sizeof(BslListNode));
|
||||
if (pNewNode == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
|
||||
return BSL_MALLOC_FAIL;
|
||||
}
|
||||
|
||||
pNewNode->data = pData;
|
||||
|
||||
/* set the new node as the first and last node of list */
|
||||
pNewNode->next = NULL;
|
||||
pNewNode->prev = NULL;
|
||||
pList->first = pNewNode;
|
||||
pList->last = pNewNode;
|
||||
pList->curr = pNewNode;
|
||||
pList->count++;
|
||||
return BSL_SUCCESS;
|
||||
} else {
|
||||
if (enPosition == BSL_LIST_POS_AFTER) {
|
||||
pList->curr = pList->last;
|
||||
} else if (enPosition == BSL_LIST_POS_BEFORE) {
|
||||
pList->curr = pList->first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((enPosition == BSL_LIST_POS_AFTER) || (enPosition == BSL_LIST_POS_END)) {
|
||||
if (enPosition == BSL_LIST_POS_END) {
|
||||
pList->curr = pList->last;
|
||||
}
|
||||
|
||||
return BslListAddAfterCurr(pList, pData);
|
||||
} else {
|
||||
if (enPosition == BSL_LIST_POS_BEGIN) {
|
||||
pList->curr = pList->first;
|
||||
}
|
||||
|
||||
return BslListInsertBeforeCurr(pList, pData);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t BSL_LIST_AddElement(BslList *pList, void *pData, BslListPosition enPosition)
|
||||
{
|
||||
/* check for missing argument */
|
||||
if (pList == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* we are doing a range checking. the same thing is done in another way for clarity */
|
||||
if (enPosition < BSL_LIST_POS_BEFORE || enPosition > BSL_LIST_POS_END) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (pData == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_LIST_DATA_NOT_AVAILABLE);
|
||||
return BSL_LIST_DATA_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return (int32_t)BSL_LIST_AddElementInt(pList, pData, enPosition);
|
||||
}
|
||||
|
||||
int32_t BSL_LIST_SetMaxElements(int32_t iMaxElements)
|
||||
{
|
||||
if (iMaxElements < 0xffff || iMaxElements > 0xfffffff) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
|
||||
g_maxListCount = iMaxElements;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_LIST_GetMaxElements(void)
|
||||
{
|
||||
return g_maxListCount;
|
||||
}
|
||||
|
||||
void BSL_LIST_DeleteAll(BslList *pList, BSL_LIST_PFUNC_FREE pfFreeFunc)
|
||||
{
|
||||
BslListNode *pNode = NULL;
|
||||
BslListNode *pNext = NULL;
|
||||
|
||||
/* check for missing argument */
|
||||
if (pList == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
pNode = pList->first;
|
||||
|
||||
/* delete each node one by one */
|
||||
while (pNode != NULL) {
|
||||
pNext = pNode->next;
|
||||
if (pfFreeFunc == NULL) {
|
||||
BSL_SAL_FREE(pNode->data);
|
||||
} else {
|
||||
pfFreeFunc(pNode->data);
|
||||
pNode->data = NULL;
|
||||
}
|
||||
|
||||
BSL_SAL_FREE(pNode);
|
||||
pNode = pNext;
|
||||
pList->count--;
|
||||
}
|
||||
|
||||
pList->first = pList->last = pList->curr = NULL;
|
||||
}
|
||||
|
||||
void BSL_LIST_DeleteCurrent(BslList *pList, BSL_LIST_PFUNC_FREE pfFreeFunc)
|
||||
{
|
||||
BslListNode *pNode = NULL;
|
||||
|
||||
/* check for missing argument */
|
||||
if (pList == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pList->curr != NULL) {
|
||||
/* delete current and set prev and next appropriately */
|
||||
if (pList->curr->next != NULL) {
|
||||
pList->curr->next->prev = pList->curr->prev;
|
||||
} else {
|
||||
pList->last = pList->curr->prev;
|
||||
}
|
||||
|
||||
if (pList->curr->prev != NULL) {
|
||||
pList->curr->prev->next = pList->curr->next;
|
||||
} else {
|
||||
pList->first = pList->curr->next;
|
||||
}
|
||||
|
||||
pNode = pList->curr;
|
||||
|
||||
pList->curr = pList->curr->next;
|
||||
pList->count--;
|
||||
|
||||
if (pfFreeFunc == NULL) {
|
||||
BSL_SAL_FREE(pNode->data);
|
||||
} else {
|
||||
pfFreeFunc(pNode->data);
|
||||
}
|
||||
|
||||
BSL_SAL_FREE(pNode);
|
||||
}
|
||||
}
|
||||
|
||||
void BSL_LIST_DetachCurrent(BslList *pList)
|
||||
{
|
||||
/* check for missing argument */
|
||||
BslListNode *tmpCurr = NULL;
|
||||
if (pList == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
tmpCurr = pList->curr; // get the current node
|
||||
|
||||
if (tmpCurr != NULL) {
|
||||
/* delete current and set prev and next appropriately */
|
||||
if (tmpCurr->next != NULL) { // check for last node
|
||||
// current node is not the last node
|
||||
tmpCurr->next->prev = tmpCurr->prev;
|
||||
|
||||
// update the current node and point it to the next node
|
||||
pList->curr = tmpCurr->next;
|
||||
} else {
|
||||
// current node is the last node
|
||||
pList->last = tmpCurr->prev;
|
||||
|
||||
// update the current node and point it to the last node
|
||||
pList->curr = pList->last;
|
||||
}
|
||||
|
||||
if (tmpCurr->prev != NULL) { // check for the first node
|
||||
// current node is not the first node
|
||||
tmpCurr->prev->next = tmpCurr->next;
|
||||
} else {
|
||||
// current node is the first node
|
||||
pList->first = tmpCurr->next;
|
||||
}
|
||||
|
||||
// we have already updated the pList->curr pointer appropriately
|
||||
pList->count--;
|
||||
|
||||
// now we must free the temp current node
|
||||
BSL_SAL_FREE(tmpCurr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup bsl_list
|
||||
* @brief Searches for an element and as well return immediately after internal error
|
||||
*
|
||||
* @param pList [IN] List in which object is searched for.
|
||||
* @param pSearchFor [IN] Object to be searched for.
|
||||
* @param pSearcher [IN] Search Function to be used.
|
||||
* @param pstErr [OUT] Update the Internal Error if Any. If pstErr is not equal to NULL. If NULL this will be ignored.
|
||||
* @retval void *
|
||||
*/
|
||||
static void *BSL_ListSearchInt(BslList *pList, const void *pSearchFor, BSL_LIST_PFUNC_CMP pSearcher, int32_t *pstErr)
|
||||
{
|
||||
/* temporarily stores current node */
|
||||
BslListNode *pstTempCurr = NULL;
|
||||
|
||||
/* check for missing argument */
|
||||
if (pList == NULL || pSearchFor == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pstTempCurr = pList->curr;
|
||||
|
||||
/* parse all nodes one by one */
|
||||
for ((pList)->curr = (pList)->first; (pList)->curr != NULL; (pList)->curr = (pList)->curr->next) {
|
||||
if (pSearcher == NULL) {
|
||||
/* if pSearcher is NULL, use memcmp */
|
||||
if (memcmp(pList->curr->data, pSearchFor, (uint32_t)pList->dataSize) == 0) {
|
||||
return pList->curr->data;
|
||||
}
|
||||
} else {
|
||||
int32_t retVal = pSearcher(pList->curr->data, pSearchFor);
|
||||
if (retVal == SEC_INT_ERROR && pstErr != NULL) {
|
||||
*pstErr = SEC_INT_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (retVal == 0) {
|
||||
return pList->curr->data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* no match found */
|
||||
pList->curr = pstTempCurr;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *BSL_LIST_Search(BslList *pList, const void *pSearchFor, BSL_LIST_PFUNC_CMP pSearcher, int32_t *pstErr)
|
||||
{
|
||||
return BSL_ListSearchInt(pList, pSearchFor, pSearcher, pstErr);
|
||||
}
|
||||
|
||||
void *BSL_LIST_SearchEx(BslList *pList, const void *pSearchFor, BSL_LIST_PFUNC_CMP pSearcher)
|
||||
{
|
||||
return BSL_ListSearchInt(pList, pSearchFor, pSearcher, NULL);
|
||||
}
|
||||
|
||||
void *BSL_LIST_GetIndexNode(uint32_t ulIndex, BslList *pList)
|
||||
{
|
||||
if (pList == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ulIndex >= (uint32_t)pList->count) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (BSL_LIST_GET_FIRST(pList) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (uint32_t ulIter = 0; ulIter < ulIndex; ulIter++) {
|
||||
if (BSL_LIST_GET_NEXT(pList) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pList->curr->data;
|
||||
}
|
||||
|
||||
BslList *BSL_LIST_Copy(BslList *pSrcList, BSL_LIST_PFUNC_DUP pFuncCpy, BSL_LIST_PFUNC_FREE pfFreeFunc)
|
||||
{
|
||||
void *pDstData = NULL;
|
||||
|
||||
if (pSrcList == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* we will first get the source data and if successful go ahead */
|
||||
void *pSrcData = BSL_LIST_GET_FIRST(pSrcList);
|
||||
if (pSrcData == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BslList *pDstList = BSL_LIST_New(pSrcList->dataSize);
|
||||
if (pDstList == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int32_t i = 1; pSrcData != NULL && i <= BSL_LIST_COUNT(pSrcList); i++) {
|
||||
if (pFuncCpy != NULL) {
|
||||
pDstData = pFuncCpy(pSrcData);
|
||||
} else {
|
||||
uint32_t dataLen = (uint32_t)(pSrcList->dataSize);
|
||||
pDstData = BSL_SAL_Calloc(1, dataLen);
|
||||
/* we must do NULL check */
|
||||
if (pDstData == NULL) {
|
||||
BSL_LIST_FREE(pDstList, pfFreeFunc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)memcpy_s(pDstData, dataLen, pSrcData, dataLen);
|
||||
}
|
||||
|
||||
if (pDstData == NULL) {
|
||||
BSL_LIST_FREE(pDstList, pfFreeFunc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (BSL_LIST_AddElement(pDstList, pDstData, BSL_LIST_POS_AFTER) != BSL_SUCCESS) {
|
||||
if (pfFreeFunc != NULL) {
|
||||
pfFreeFunc(pDstData);
|
||||
pDstData = NULL;
|
||||
} else {
|
||||
BSL_SAL_FREE(pDstData);
|
||||
}
|
||||
|
||||
BSL_LIST_FREE(pDstList, pfFreeFunc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pSrcData = BSL_LIST_GET_NEXT(pSrcList);
|
||||
}
|
||||
|
||||
return pDstList;
|
||||
}
|
||||
|
||||
void BSL_LIST_DeleteAllAfterSort(BslList *pList)
|
||||
{
|
||||
BslListNode *pNode = NULL;
|
||||
BslListNode *pNext = NULL;
|
||||
|
||||
/* check for missing argument */
|
||||
if (pList == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
pNode = pList->first;
|
||||
|
||||
/* delete each node one by one */
|
||||
while (pNode != NULL) {
|
||||
pNext = pNode->next;
|
||||
BSL_SAL_FREE(pNode);
|
||||
pNode = pNext;
|
||||
pList->count--;
|
||||
}
|
||||
|
||||
pList->first = pList->last = pList->curr = NULL;
|
||||
}
|
||||
|
||||
BslList *BSL_LIST_Sort(BslList *pList, BSL_LIST_PFUNC_CMP pfCmp)
|
||||
{
|
||||
if (pfCmp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t iRet = BSL_ListSortInternal(pList, pfCmp);
|
||||
if (iRet != BSL_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pList;
|
||||
}
|
||||
|
||||
void BSL_LIST_FreeWithoutData(BslList *pstList)
|
||||
{
|
||||
BslListNode *node = NULL;
|
||||
BslListNode *next = NULL;
|
||||
|
||||
if (pstList != NULL) {
|
||||
node = pstList->first;
|
||||
while (node != NULL) {
|
||||
next = node->next;
|
||||
BSL_SAL_FREE(node);
|
||||
node = next;
|
||||
}
|
||||
|
||||
BSL_SAL_FREE(pstList);
|
||||
}
|
||||
}
|
||||
|
||||
void BSL_LIST_RevList(BslList *pstList)
|
||||
{
|
||||
struct BslListNode *pstTemp = NULL;
|
||||
|
||||
if (pstList == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
pstList->curr = pstList->first;
|
||||
|
||||
while (pstList->curr != NULL) {
|
||||
pstTemp = pstList->curr->next;
|
||||
pstList->curr->next = pstList->curr->prev;
|
||||
pstList->curr->prev = pstTemp;
|
||||
pstList->curr = pstTemp;
|
||||
}
|
||||
|
||||
pstList->curr = pstList->first;
|
||||
pstList->first = pstList->last;
|
||||
pstList->last = pstList->curr;
|
||||
pstList->curr = pstList->first;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BslList *BSL_ListConcatToEmptyList(BslList *pDestList, const BslList *pSrcList)
|
||||
{
|
||||
pDestList->count = pSrcList->count;
|
||||
pDestList->first = pSrcList->first;
|
||||
pDestList->last = pSrcList->last;
|
||||
pDestList->curr = pDestList->first;
|
||||
|
||||
return pDestList;
|
||||
}
|
||||
|
||||
BslList *BSL_ListConcatToNonEmptyList(BslList *pDestList, const BslList *pSrcList)
|
||||
{
|
||||
if ((pDestList->count + pSrcList->count) > g_maxListCount) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pDestList->count += pSrcList->count;
|
||||
pSrcList->first->prev = pDestList->last;
|
||||
pDestList->last->next = pSrcList->first;
|
||||
pDestList->last = pSrcList->last;
|
||||
|
||||
return pDestList;
|
||||
}
|
||||
|
||||
BslList *BSL_LIST_Concat(BslList *pDestList, const BslList *pSrcList)
|
||||
{
|
||||
if (pDestList == NULL || pSrcList == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pSrcList->count == 0) {
|
||||
return pDestList;
|
||||
}
|
||||
|
||||
if (pDestList->count == 0) {
|
||||
return BSL_ListConcatToEmptyList(pDestList, pSrcList);
|
||||
}
|
||||
|
||||
return BSL_ListConcatToNonEmptyList(pDestList, pSrcList);
|
||||
}
|
||||
#endif /* HITLS_BSL_LIST */
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_LIST
|
||||
|
||||
#include "securec.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_list.h"
|
||||
|
||||
BslListNode *BSL_LIST_FirstNode(const BslList *list)
|
||||
{
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return list->first;
|
||||
}
|
||||
|
||||
void *BSL_LIST_GetData(const BslListNode *pstNode)
|
||||
{
|
||||
if (pstNode == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pstNode->data;
|
||||
}
|
||||
|
||||
BslListNode *BSL_LIST_GetNextNode(const BslList *pstList, const BslListNode *pstListNode)
|
||||
{
|
||||
if (pstList == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pstListNode != NULL) {
|
||||
return pstListNode->next;
|
||||
}
|
||||
|
||||
return pstList->first;
|
||||
}
|
||||
|
||||
void *BSL_LIST_GetIndexNodeEx(uint32_t ulIndex, const BslListNode *pstListNode, const BslList *pstList)
|
||||
{
|
||||
const BslListNode *pstTmpListNode = NULL;
|
||||
(void)pstListNode;
|
||||
if (pstList == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ulIndex >= (uint32_t)pstList->count) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pstList->first == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pstTmpListNode = pstList->first;
|
||||
for (uint32_t ulIter = 0; ulIter < ulIndex; ulIter++) {
|
||||
pstTmpListNode = pstTmpListNode->next;
|
||||
if (pstTmpListNode == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pstTmpListNode->data;
|
||||
}
|
||||
|
||||
BslListNode *BSL_LIST_GetPrevNode(const BslListNode *pstListNode)
|
||||
{
|
||||
if (pstListNode == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pstListNode->prev;
|
||||
}
|
||||
|
||||
void BSL_LIST_DeleteNode(BslList *pstList, const BslListNode *pstListNode, BSL_LIST_PFUNC_FREE pfFreeFunc)
|
||||
{
|
||||
BslListNode *pstCurrentNode = NULL;
|
||||
|
||||
if (pstList == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
pstCurrentNode = pstList->first;
|
||||
|
||||
while (pstCurrentNode != NULL) {
|
||||
if (pstCurrentNode == pstListNode) {
|
||||
// found matching node, delete this node and adjust the list
|
||||
if ((pstCurrentNode->next) != NULL) {
|
||||
pstCurrentNode->next->prev = pstCurrentNode->prev;
|
||||
} else {
|
||||
pstList->last = pstCurrentNode->prev;
|
||||
}
|
||||
|
||||
if ((pstCurrentNode->prev) != NULL) {
|
||||
pstCurrentNode->prev->next = pstCurrentNode->next;
|
||||
} else {
|
||||
pstList->first = pstCurrentNode->next;
|
||||
}
|
||||
if (pstCurrentNode == pstList->curr) {
|
||||
pstList->curr = pstList->curr->next;
|
||||
}
|
||||
pstList->count--;
|
||||
|
||||
if (pfFreeFunc == NULL) {
|
||||
BSL_SAL_FREE(pstCurrentNode->data);
|
||||
} else {
|
||||
pfFreeFunc(pstCurrentNode->data);
|
||||
}
|
||||
|
||||
BSL_SAL_FREE(pstCurrentNode);
|
||||
return;
|
||||
}
|
||||
|
||||
pstCurrentNode = pstCurrentNode->next;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void BSL_LIST_DetachNode(BslList *pstList, BslListNode **pstListNode)
|
||||
{
|
||||
if (pstList == NULL || pstListNode == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
BslListNode *pstCurrentNode = pstList->first;
|
||||
while (pstCurrentNode != NULL) {
|
||||
if (pstCurrentNode == *pstListNode) {
|
||||
// found matching node, delete this node and adjust the list
|
||||
if ((pstCurrentNode->next) != NULL) {
|
||||
pstCurrentNode->next->prev = pstCurrentNode->prev;
|
||||
*pstListNode = pstCurrentNode->next; // update the current node and point it to the next node
|
||||
} else {
|
||||
pstList->last = pstCurrentNode->prev;
|
||||
*pstListNode = pstList->last;
|
||||
}
|
||||
|
||||
if ((pstCurrentNode->prev) != NULL) {
|
||||
pstCurrentNode->prev->next = pstCurrentNode->next;
|
||||
} else {
|
||||
pstList->first = pstCurrentNode->next;
|
||||
}
|
||||
|
||||
pstList->count--;
|
||||
|
||||
BSL_SAL_FREE(pstCurrentNode);
|
||||
return;
|
||||
}
|
||||
|
||||
pstCurrentNode = pstCurrentNode->next;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif /* HITLS_BSL_LIST */
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_LIST
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "bsl_list.h"
|
||||
#include "bsl_err_internal.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_list_internal.h"
|
||||
|
||||
#define SEC_MAX_QSORT_SIZE (64 * 1024 * 1024)
|
||||
#define SEC_MIN_QSORT_SIZE 10000
|
||||
|
||||
static uint32_t g_maxQsortElem = 100000;
|
||||
|
||||
BslList *BSL_LIST_New(int32_t dataSize)
|
||||
{
|
||||
BslList *pstList = NULL;
|
||||
|
||||
if (dataSize < 0) {
|
||||
return NULL;
|
||||
}
|
||||
pstList = BSL_SAL_Calloc(1, sizeof(BslList));
|
||||
if (pstList == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pstList->curr = NULL;
|
||||
pstList->last = NULL;
|
||||
pstList->first = NULL;
|
||||
pstList->dataSize = dataSize;
|
||||
pstList->count = 0;
|
||||
|
||||
return pstList;
|
||||
}
|
||||
|
||||
void *BSL_LIST_Prev(BslList *pstList)
|
||||
{
|
||||
if (pstList == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pstList->curr != NULL) {
|
||||
pstList->curr = pstList->curr->prev;
|
||||
} else {
|
||||
pstList->curr = pstList->last;
|
||||
}
|
||||
|
||||
if (pstList->curr != NULL) {
|
||||
return (void *)&(pstList->curr->data);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *BSL_LIST_Next(BslList *pstList)
|
||||
{
|
||||
if (pstList == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pstList->curr != NULL) {
|
||||
pstList->curr = pstList->curr->next;
|
||||
} else {
|
||||
pstList->curr = pstList->first;
|
||||
}
|
||||
|
||||
if (pstList->curr != NULL) {
|
||||
return (void *)&(pstList->curr->data);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *BSL_LIST_Last(BslList *pstList)
|
||||
{
|
||||
if (pstList == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pstList->curr = pstList->last;
|
||||
|
||||
if (pstList->curr != NULL) {
|
||||
return (void *)&(pstList->curr->data);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *BSL_LIST_First(BslList *pstList)
|
||||
{
|
||||
if (pstList == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pstList->curr = pstList->first;
|
||||
|
||||
if (pstList->curr != NULL) {
|
||||
return (void *)&(pstList->curr->data);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *BSL_LIST_Curr(const BslList *pstList)
|
||||
{
|
||||
if (pstList == NULL || pstList->curr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (void *)&(pstList->curr->data);
|
||||
}
|
||||
|
||||
int32_t BSL_LIST_GetElmtIndex(const void *elmt, BslList *pstList)
|
||||
{
|
||||
int32_t idx = 0;
|
||||
void *tmpElmt = NULL;
|
||||
|
||||
if (pstList == NULL) {
|
||||
return -1; // -1 means that the corresponding element is not found
|
||||
}
|
||||
|
||||
BslListNode *tmp = (void *)pstList->curr;
|
||||
|
||||
for ((pstList)->curr = (pstList)->first; (pstList)->curr != NULL; (pstList)->curr = (pstList)->curr->next) {
|
||||
tmpElmt = pstList->curr->data;
|
||||
if (tmpElmt == NULL) {
|
||||
break;
|
||||
}
|
||||
if (tmpElmt != elmt) {
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
pstList->curr = tmp;
|
||||
return idx;
|
||||
}
|
||||
|
||||
pstList->curr = tmp;
|
||||
|
||||
return -1; // -1 means that the corresponding element is not found
|
||||
}
|
||||
|
||||
int32_t BSL_ListSortInternal(BslList *pList, BSL_LIST_PFUNC_CMP cmp)
|
||||
{
|
||||
void **sortArray = NULL;
|
||||
void *elmt = NULL;
|
||||
int32_t i;
|
||||
|
||||
/* Make sure pList is not NULL */
|
||||
if (pList == NULL || g_maxQsortElem < (uint32_t)pList->count) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Create array of elements so we can qsort the pList */
|
||||
sortArray = BSL_SAL_Calloc((uint32_t)pList->count, sizeof(void *));
|
||||
if (sortArray == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
|
||||
return BSL_MALLOC_FAIL;
|
||||
}
|
||||
|
||||
/* Copy the elements from the pList into the sort array */
|
||||
for (pList->curr = pList->first, i = 0; pList->curr; pList->curr = pList->curr->next, i++) {
|
||||
elmt = (void *)pList->curr->data;
|
||||
if (elmt == NULL || i >= pList->count) {
|
||||
break;
|
||||
}
|
||||
|
||||
sortArray[i] = elmt;
|
||||
}
|
||||
/* sort encoded elements */
|
||||
qsort(sortArray, (uint32_t)pList->count, sizeof(void *), cmp);
|
||||
|
||||
for (pList->curr = pList->first, i = 0; pList->curr != NULL; pList->curr = pList->curr->next, i++) {
|
||||
pList->curr->data = sortArray[i];
|
||||
}
|
||||
|
||||
BSL_SAL_FREE(sortArray);
|
||||
|
||||
/* Return the sorted pList */
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_LIST_SetMaxQsortCount(uint32_t uiQsortSize)
|
||||
{
|
||||
if ((uiQsortSize > SEC_MAX_QSORT_SIZE) || (uiQsortSize < SEC_MIN_QSORT_SIZE)) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
|
||||
g_maxQsortElem = uiQsortSize;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t BSL_LIST_GetMaxQsortCount(void)
|
||||
{
|
||||
return g_maxQsortElem;
|
||||
}
|
||||
#endif /* HITLS_BSL_LIST */
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef BSL_LOG_INTERNAL_H
|
||||
#define BSL_LOG_INTERNAL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hitls_build.h"
|
||||
#include "bsl_log.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_BSL_LOG
|
||||
|
||||
#define BSL_LOG_BUF_SIZE 1024U
|
||||
|
||||
/**
|
||||
* @ingroup bsl_log
|
||||
* @brief four-parameter dotting log function
|
||||
* @attention A maximum of four parameters can be contained in the formatted string.
|
||||
* If the number of parameters is less than four, 0s or NULL must be added.
|
||||
* If the number of parameters exceeds four, multiple invoking is required.
|
||||
* Only the BSL_LOG_BINLOG_FIXLEN macro can be invoked. This macro cannot be redefined.
|
||||
* @param logId [IN] Log ID
|
||||
* @param logLevel [IN] Log level
|
||||
* @param logType [IN] String label
|
||||
* @param format [IN] Format string. Only literal strings are allowed. Variables are not allowed.
|
||||
* @param para1 [IN] Parameter 1
|
||||
* @param para2 [IN] Parameter 2
|
||||
* @param para3 [IN] Parameter 3
|
||||
* @param para4 [IN] Parameter 4
|
||||
*/
|
||||
void BSL_LOG_BinLogFixLen(uint32_t logId, uint32_t logLevel, uint32_t logType,
|
||||
void *format, void *para1, void *para2, void *para3, void *para4);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_log
|
||||
* @brief one-parameter dotting log function
|
||||
* @attention The formatted character string contains only one parameter, which is %s.
|
||||
* For a pure character string, use LOG_BinLogFixLen
|
||||
* Only the BSL_LOG_BINLOG_VARLEN macro can be invoked. This macro cannot be redefined.
|
||||
* @param logId [IN] Log ID
|
||||
* @param logLevel [IN] Log level
|
||||
* @param logType [IN] String label
|
||||
* @param format [IN] Format string. Only literal strings are allowed. Variables are not allowed.
|
||||
* @param para [IN] Parameter
|
||||
*/
|
||||
void BSL_LOG_BinLogVarLen(uint32_t logId, uint32_t logLevel, uint32_t logType, void *format, void *para);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_log
|
||||
* @brief four-parameter dotting log macro
|
||||
* @attention A maximum of four parameters can be contained in the formatted string.
|
||||
* If the number of parameters is less than four, 0s or NULL must be added.
|
||||
* If the number of parameters exceeds four, multiple invoking is required.
|
||||
* @param logId [IN] Log ID
|
||||
* @param logLevel [IN] Log level
|
||||
* @param logType [IN] String label
|
||||
* @param format [IN] Format string. Only literal strings are allowed. Variables are not allowed.
|
||||
* @param para1 [IN] Parameter 1
|
||||
* @param para2 [IN] Parameter 2
|
||||
* @param para3 [IN] Parameter 3
|
||||
* @param para4 [IN] Parameter 4
|
||||
*/
|
||||
#define BSL_LOG_BINLOG_FIXLEN(logId, logLevel, logType, format, para1, para2, para3, para4) \
|
||||
BSL_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_log
|
||||
* @brief one-parameter dotting log macro
|
||||
* @attention The formatted character string contains only one parameter, which is %s.
|
||||
* For a pure character string, use LOG_BinLogFixLen
|
||||
* @param logId [IN] Log ID
|
||||
* @param logLevel [IN] Log level
|
||||
* @param logType [IN] String label
|
||||
* @param format [IN] Format string. Only literal strings are allowed. Variables are not allowed.
|
||||
* @param para [IN] Parameter
|
||||
*/
|
||||
#define BSL_LOG_BINLOG_VARLEN(logId, logLevel, logType, format, para) \
|
||||
BSL_LOG_BinLogVarLen(logId, logLevel, logType, \
|
||||
(void *)(uintptr_t)(const void *)(format), (void *)(uintptr_t)(const void *)(para))
|
||||
|
||||
#else
|
||||
|
||||
#define BSL_LOG_BINLOG_FIXLEN(logId, logLevel, logType, format, para1, para2, para3, para4)
|
||||
#define BSL_LOG_BINLOG_VARLEN(logId, logLevel, logType, format, para)
|
||||
|
||||
#endif /* HITLS_BSL_LOG */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BSL_LOG_INTERNAL_H
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_LOG
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "securec.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_log.h"
|
||||
#include "bsl_log_internal.h"
|
||||
|
||||
/* string of HiTLS version */
|
||||
static char g_openHiTLSVersion[HITLS_VERSION_LEN] = OPENHITLS_VERSION_S;
|
||||
static uint32_t g_openHiTLSNumVersion = OPENHITLS_VERSION_I;
|
||||
|
||||
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_openHiTLSVersion);
|
||||
if (memcpy_s(version, *versionLen, g_openHiTLSVersion, len) != EOK) {
|
||||
return BSL_MEMCPY_FAIL;
|
||||
}
|
||||
|
||||
*versionLen = len;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t BSL_LOG_GetVersionNum(void)
|
||||
{
|
||||
return g_openHiTLSNumVersion;
|
||||
}
|
||||
|
||||
static BSL_LOG_BinLogFixLenFunc g_fixLenFunc = NULL;
|
||||
static BSL_LOG_BinLogVarLenFunc g_varLenFunc = NULL;
|
||||
static uint32_t g_binlogLevel = BSL_LOG_LEVEL_ERR; // error-level is enabled by default
|
||||
static uint32_t g_binlogType = BSL_LOG_BINLOG_TYPE_RUN; // type run is enabled by default, other types can be added.
|
||||
|
||||
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 BSL_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 BSL_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);
|
||||
}
|
||||
}
|
||||
#endif /* HITLS_BSL_LOG */
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef BSL_OBJ_INTERNAL_H
|
||||
#define BSL_OBJ_INTERNAL_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_OBJ
|
||||
|
||||
#include "bsl_obj.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
BSL_OID_GLOBAL,
|
||||
BSL_OID_HEAP
|
||||
} BslOidFlag;
|
||||
|
||||
typedef struct {
|
||||
uint32_t octetLen;
|
||||
char *octs;
|
||||
uint32_t flags;
|
||||
} BslOidString;
|
||||
|
||||
typedef struct {
|
||||
BslOidString strOid;
|
||||
const char *oidName;
|
||||
BslCid cid;
|
||||
} BslOidInfo;
|
||||
|
||||
typedef struct {
|
||||
BslCid cid;
|
||||
int32_t min;
|
||||
int32_t max;
|
||||
} BslAsn1StrInfo;
|
||||
|
||||
BslCid BSL_OBJ_GetCIDFromOid(BslOidString *oid);
|
||||
|
||||
BslOidString *BSL_OBJ_GetOidFromCID(BslCid inputCid);
|
||||
|
||||
BslCid BSL_OBJ_GetHashIdFromSignId(BslCid signAlg);
|
||||
|
||||
BslCid BSL_OBJ_GetAsymIdFromSignId(BslCid signAlg);
|
||||
|
||||
const char *BSL_OBJ_GetOidNameFromOid(const BslOidString *oid);
|
||||
|
||||
BslCid BSL_OBJ_GetSignIdFromHashAndAsymId(BslCid asymAlg, BslCid hashAlg);
|
||||
|
||||
const BslAsn1StrInfo *BSL_OBJ_GetAsn1StrFromCid(BslCid cid);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // BSL_OBJ_INTERNAL_H
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_OBJ
|
||||
#include <stddef.h>
|
||||
#include "bsl_obj.h"
|
||||
#include "bsl_obj_internal.h"
|
||||
#include "securec.h"
|
||||
|
||||
typedef struct BslSignIdMap {
|
||||
BslCid signId;
|
||||
BslCid asymId;
|
||||
BslCid hashId;
|
||||
} BSL_SignIdMap;
|
||||
|
||||
BSL_SignIdMap g_signIdMap[] = {
|
||||
{BSL_CID_SHA1WITHRSA, BSL_CID_RSA, BSL_CID_SHA1},
|
||||
{BSL_CID_SHA224WITHRSAENCRYPTION, BSL_CID_RSA, BSL_CID_SHA224},
|
||||
{BSL_CID_SHA256WITHRSAENCRYPTION, BSL_CID_RSA, BSL_CID_SHA256},
|
||||
{BSL_CID_SHA384WITHRSAENCRYPTION, BSL_CID_RSA, BSL_CID_SHA384},
|
||||
{BSL_CID_SHA512WITHRSAENCRYPTION, BSL_CID_RSA, BSL_CID_SHA512},
|
||||
{BSL_CID_RSASSAPSS, BSL_CID_RSA, BSL_CID_UNKNOWN},
|
||||
{BSL_CID_SM3WITHRSAENCRYPTION, BSL_CID_RSA, BSL_CID_SM3},
|
||||
{BSL_CID_DSAWITHSHA1, BSL_CID_DSA, BSL_CID_SHA1},
|
||||
{BSL_CID_DSAWITHSHA224, BSL_CID_DSA, BSL_CID_SHA224},
|
||||
{BSL_CID_DSAWITHSHA256, BSL_CID_DSA, BSL_CID_SHA256},
|
||||
{BSL_CID_DSAWITHSHA384, BSL_CID_DSA, BSL_CID_SHA384},
|
||||
{BSL_CID_DSAWITHSHA512, BSL_CID_DSA, BSL_CID_SHA512},
|
||||
{BSL_CID_ECDSAWITHSHA1, BSL_CID_ECDSA, BSL_CID_SHA1},
|
||||
{BSL_CID_ECDSAWITHSHA224, BSL_CID_ECDSA, BSL_CID_SHA224},
|
||||
{BSL_CID_ECDSAWITHSHA256, BSL_CID_ECDSA, BSL_CID_SHA256},
|
||||
{BSL_CID_ECDSAWITHSHA384, BSL_CID_ECDSA, BSL_CID_SHA384},
|
||||
{BSL_CID_ECDSAWITHSHA512, BSL_CID_ECDSA, BSL_CID_SHA512},
|
||||
{BSL_CID_SM2DSAWITHSM3, BSL_CID_SM2, BSL_CID_SM3},
|
||||
{BSL_CID_SM2DSAWITHSHA1, BSL_CID_SM2, BSL_CID_SHA1},
|
||||
{BSL_CID_SM2DSAWITHSHA256, BSL_CID_SM2, BSL_CID_SHA256},
|
||||
};
|
||||
|
||||
BslCid BSL_OBJ_GetHashIdFromSignId(BslCid signAlg)
|
||||
{
|
||||
if (signAlg == BSL_CID_UNKNOWN) {
|
||||
return BSL_CID_UNKNOWN;
|
||||
}
|
||||
for (uint32_t iter = 0; iter < sizeof(g_signIdMap) / sizeof(BSL_SignIdMap); iter++) {
|
||||
if (signAlg == g_signIdMap[iter].signId) {
|
||||
return g_signIdMap[iter].hashId;
|
||||
}
|
||||
}
|
||||
return BSL_CID_UNKNOWN;
|
||||
}
|
||||
|
||||
BslCid BSL_OBJ_GetAsymIdFromSignId(BslCid signAlg)
|
||||
{
|
||||
if (signAlg == BSL_CID_UNKNOWN) {
|
||||
return BSL_CID_UNKNOWN;
|
||||
}
|
||||
for (uint32_t iter = 0; iter < sizeof(g_signIdMap) / sizeof(BSL_SignIdMap); iter++) {
|
||||
if (signAlg == g_signIdMap[iter].signId) {
|
||||
return g_signIdMap[iter].asymId;
|
||||
}
|
||||
}
|
||||
return BSL_CID_UNKNOWN;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_OBJ
|
||||
#include <stddef.h>
|
||||
#include "bsl_obj.h"
|
||||
#include "bsl_obj_internal.h"
|
||||
#include "securec.h"
|
||||
|
||||
BslOidInfo g_oidTable[] = {
|
||||
{{9, "\140\206\110\1\145\3\4\1\2", BSL_OID_GLOBAL}, "AES128-CBC", BSL_CID_AES128_CBC},
|
||||
{{9, "\140\206\110\1\145\3\4\1\26", BSL_OID_GLOBAL}, "AES192-CBC", BSL_CID_AES192_CBC},
|
||||
{{9, "\140\206\110\1\145\3\4\1\52", BSL_OID_GLOBAL}, "AES256-CBC", BSL_CID_AES256_CBC},
|
||||
{{8, "\52\201\34\317\125\1\150\2", BSL_OID_GLOBAL}, "SM4-CBC", BSL_CID_SM4_CBC},
|
||||
{{9, "\52\206\110\206\367\15\1\1\1", BSL_OID_GLOBAL}, "RSAENCRYPTION", BSL_CID_RSA}, // rsa subkey
|
||||
{{9, "\52\206\110\206\367\15\1\1\12", BSL_OID_GLOBAL}, "RSASSAPSS", BSL_CID_RSASSAPSS},
|
||||
{{9, "\52\206\110\206\367\15\1\1\4", BSL_OID_GLOBAL}, "MD5WITHRSA", BSL_CID_MD5WITHRSA},
|
||||
{{9, "\52\206\110\206\367\15\1\1\5", BSL_OID_GLOBAL}, "SHA1WITHRSA", BSL_CID_SHA1WITHRSA},
|
||||
{{9, "\52\206\110\206\367\15\1\1\16", BSL_OID_GLOBAL}, "SHA224WITHRSA", BSL_CID_SHA224WITHRSAENCRYPTION},
|
||||
{{9, "\52\206\110\206\367\15\1\1\13", BSL_OID_GLOBAL}, "SHA256WITHRSA", BSL_CID_SHA256WITHRSAENCRYPTION},
|
||||
{{9, "\52\206\110\206\367\15\1\1\14", BSL_OID_GLOBAL}, "SHA384WITHRSA", BSL_CID_SHA384WITHRSAENCRYPTION},
|
||||
{{9, "\52\206\110\206\367\15\1\1\15", BSL_OID_GLOBAL}, "SHA512WITHRSA", BSL_CID_SHA512WITHRSAENCRYPTION},
|
||||
{{8, "\52\201\34\317\125\1\203\170", BSL_OID_GLOBAL}, "SM3WITHRSA", BSL_CID_SM3WITHRSAENCRYPTION},
|
||||
{{7, "\52\206\110\316\70\4\1", BSL_OID_GLOBAL}, "DSAENCRYPTION", BSL_CID_DSA}, // dsa subkey
|
||||
{{7, "\52\206\110\316\70\4\3", BSL_OID_GLOBAL}, "DSAWITHSHA1", BSL_CID_DSAWITHSHA1},
|
||||
{{9, "\140\206\110\1\145\3\4\3\1", BSL_OID_GLOBAL}, "DSAWITHSHA224", BSL_CID_DSAWITHSHA224},
|
||||
{{9, "\140\206\110\1\145\3\4\3\2", BSL_OID_GLOBAL}, "DSAWITHSHA256", BSL_CID_DSAWITHSHA256},
|
||||
{{9, "\140\206\110\1\145\3\4\3\3", BSL_OID_GLOBAL}, "DSAWITHSHA384", BSL_CID_DSAWITHSHA384},
|
||||
{{9, "\140\206\110\1\145\3\4\3\4", BSL_OID_GLOBAL}, "DSAWITHSHA512", BSL_CID_DSAWITHSHA512},
|
||||
{{7, "\52\206\110\316\75\4\1", BSL_OID_GLOBAL}, "ECDSAWITHSHA1", BSL_CID_ECDSAWITHSHA1},
|
||||
{{8, "\52\206\110\316\75\4\3\1", BSL_OID_GLOBAL}, "ECDSAWITHSHA224", BSL_CID_ECDSAWITHSHA224},
|
||||
{{8, "\52\206\110\316\75\4\3\2", BSL_OID_GLOBAL}, "ECDSAWITHSHA256", BSL_CID_ECDSAWITHSHA256},
|
||||
{{8, "\52\206\110\316\75\4\3\3", BSL_OID_GLOBAL}, "ECDSAWITHSHA384", BSL_CID_ECDSAWITHSHA384},
|
||||
{{8, "\52\206\110\316\75\4\3\4", BSL_OID_GLOBAL}, "ECDSAWITHSHA512", BSL_CID_ECDSAWITHSHA512},
|
||||
{{8, "\52\201\34\317\125\1\203\165", BSL_OID_GLOBAL}, "SM2DSAWITHSM3", BSL_CID_SM2DSAWITHSM3},
|
||||
{{8, "\52\201\34\317\125\1\203\166", BSL_OID_GLOBAL}, "SM2DSAWITHSHA1", BSL_CID_SM2DSAWITHSHA1},
|
||||
{{8, "\52\201\34\317\125\1\203\167", BSL_OID_GLOBAL}, "SM2DSAWITHSHA256", BSL_CID_SM2DSAWITHSHA256},
|
||||
{{8, "\52\206\110\206\367\15\2\5", BSL_OID_GLOBAL}, "MD5", BSL_CID_MD5},
|
||||
{{5, "\53\16\3\2\32", BSL_OID_GLOBAL}, "SHA1", BSL_CID_SHA1},
|
||||
{{9, "\140\206\110\1\145\3\4\2\4", BSL_OID_GLOBAL}, "SHA224", BSL_CID_SHA224},
|
||||
{{9, "\140\206\110\1\145\3\4\2\1", BSL_OID_GLOBAL}, "SHA256", BSL_CID_SHA256},
|
||||
{{9, "\140\206\110\1\145\3\4\2\2", BSL_OID_GLOBAL}, "SHA384", BSL_CID_SHA384},
|
||||
{{9, "\140\206\110\1\145\3\4\2\3", BSL_OID_GLOBAL}, "SHA512", BSL_CID_SHA512},
|
||||
{{9, "\140\206\110\1\145\3\4\2\7", BSL_OID_GLOBAL}, "SHA3-224", BSL_CID_SHA3_224},
|
||||
{{9, "\140\206\110\1\145\3\4\2\10", BSL_OID_GLOBAL}, "SHA3-256", BSL_CID_SHA3_256},
|
||||
{{9, "\140\206\110\1\145\3\4\2\11", BSL_OID_GLOBAL}, "SHA3-384", BSL_CID_SHA3_384},
|
||||
{{9, "\140\206\110\1\145\3\4\2\12", BSL_OID_GLOBAL}, "SHA3-512", BSL_CID_SHA3_512},
|
||||
{{9, "\140\206\110\1\145\3\4\2\13", BSL_OID_GLOBAL}, "SHAKE128", BSL_CID_SHAKE128},
|
||||
{{9, "\140\206\110\1\145\3\4\2\14", BSL_OID_GLOBAL}, "SHAKE256", BSL_CID_SHAKE256},
|
||||
{{8, "\52\201\34\317\125\1\203\21", BSL_OID_GLOBAL}, "SM3", BSL_CID_SM3},
|
||||
{{8, "\53\6\1\5\5\10\1\1", BSL_OID_GLOBAL}, "HMAC-MD5", BSL_CID_HMAC_MD5},
|
||||
{{8, "\52\206\110\206\367\15\2\7", BSL_OID_GLOBAL}, "HMAC-SHA1", BSL_CID_HMAC_SHA1},
|
||||
{{8, "\52\206\110\206\367\15\2\10", BSL_OID_GLOBAL}, "HMAC-SHA224", BSL_CID_HMAC_SHA224},
|
||||
{{8, "\52\206\110\206\367\15\2\11", BSL_OID_GLOBAL}, "HMAC-SHA256", BSL_CID_HMAC_SHA256},
|
||||
{{8, "\52\206\110\206\367\15\2\12", BSL_OID_GLOBAL}, "HMAC-SHA384", BSL_CID_HMAC_SHA384},
|
||||
{{8, "\52\206\110\206\367\15\2\13", BSL_OID_GLOBAL}, "HMAC-SHA512", BSL_CID_HMAC_SHA512},
|
||||
{{9, "\52\206\110\206\367\15\1\5\14", BSL_OID_GLOBAL}, "PBKDF2", BSL_CID_PBKDF2},
|
||||
{{9, "\52\206\110\206\367\15\1\5\15", BSL_OID_GLOBAL}, "PBES2", BSL_CID_PBES2},
|
||||
{{9, "\53\44\3\3\2\10\1\1\7", BSL_OID_GLOBAL}, "BRAINPOOLP256R1", BSL_CID_ECC_BRAINPOOLP256R1},
|
||||
{{9, "\53\44\3\3\2\10\1\1\13", BSL_OID_GLOBAL}, "BRAINPOOLP384R1", BSL_CID_ECC_BRAINPOOLP384R1},
|
||||
{{9, "\53\44\3\3\2\10\1\1\15", BSL_OID_GLOBAL}, "BRAINPOOLP512R1", BSL_CID_ECC_BRAINPOOLP512R1},
|
||||
{{5, "\53\201\4\0\42", BSL_OID_GLOBAL}, "SECP384R1", BSL_CID_SECP384R1},
|
||||
{{5, "\53\201\4\0\43", BSL_OID_GLOBAL}, "SECP521R1", BSL_CID_SECP521R1},
|
||||
{{8, "\52\206\110\316\75\3\1\7", BSL_OID_GLOBAL}, "PRIME256V1", BSL_CID_PRIME256V1},
|
||||
{{5, "\53\201\4\0\41", BSL_OID_GLOBAL}, "PRIME224", BSL_CID_NIST_PRIME224},
|
||||
{{8, "\52\201\34\317\125\1\202\55", BSL_OID_GLOBAL}, "SM2PRIME256", BSL_CID_SM2PRIME256},
|
||||
{{3, "\125\35\43", BSL_OID_GLOBAL}, "AuthorityKeyIdentifier", BSL_CID_CE_AUTHORITYKEYID},
|
||||
{{3, "\125\35\16", BSL_OID_GLOBAL}, "SubjectKeyIdentifier", BSL_CID_CE_SUBJECTKEYID},
|
||||
{{3, "\125\35\17", BSL_OID_GLOBAL}, "KeyUsage", BSL_CID_CE_KEYUSAGE},
|
||||
{{3, "\125\35\21", BSL_OID_GLOBAL}, "SubjectAltName", BSL_CID_CE_SUBJECTALTNAME},
|
||||
{{3, "\125\35\23", BSL_OID_GLOBAL}, "BasicConstraints", BSL_CID_CE_BASICCONSTRAINTS},
|
||||
{{3, "\125\35\45", BSL_OID_GLOBAL}, "ExtendedKeyUsage", BSL_CID_CE_EXTENDEDKEYUSAGE},
|
||||
{{8, "\53\6\1\5\5\7\3\1", BSL_OID_GLOBAL}, "ServerAuth", BSL_CID_CE_SERVERAUTH},
|
||||
{{8, "\53\6\1\5\5\7\3\2", BSL_OID_GLOBAL}, "ClientAuth", BSL_CID_CE_CLIENTAUTH},
|
||||
{{8, "\53\6\1\5\5\7\3\3", BSL_OID_GLOBAL}, "CodeSigning", BSL_CID_CE_CODESIGNING},
|
||||
{{8, "\53\6\1\5\5\7\3\4", BSL_OID_GLOBAL}, "EmailProtection", BSL_CID_CE_EMAILPROTECTION},
|
||||
{{8, "\53\6\1\5\5\7\3\10", BSL_OID_GLOBAL}, "TimeStamping", BSL_CID_CE_TIMESTAMPING},
|
||||
{{8, "\53\6\1\5\5\7\3\11", BSL_OID_GLOBAL}, "OSCPSigning", BSL_CID_CE_OSCPSIGNING},
|
||||
{{9, "\52\206\110\206\367\15\1\1\10", BSL_OID_GLOBAL}, "MGF1", BSL_CID_MGF1},
|
||||
{{7, "\52\206\110\316\75\2\1", BSL_OID_GLOBAL}, "EC-PUBLICKEY", BSL_CID_EC_PUBLICKEY}, // ecc subkey
|
||||
{{3, "\125\4\3", BSL_OID_GLOBAL}, "CN", BSL_CID_COMMONNAME},
|
||||
{{3, "\125\4\4", BSL_OID_GLOBAL}, "SN", BSL_CID_SURNAME},
|
||||
{{3, "\125\4\5", BSL_OID_GLOBAL}, "serialNumber", BSL_CID_SERIALNUMBER},
|
||||
{{3, "\125\4\6", BSL_OID_GLOBAL}, "C", BSL_CID_COUNTRYNAME},
|
||||
{{3, "\125\4\7", BSL_OID_GLOBAL}, "L", BSL_CID_LOCALITYNAME},
|
||||
{{3, "\125\4\10", BSL_OID_GLOBAL}, "ST", BSL_CID_STATEORPROVINCENAME},
|
||||
{{3, "\125\4\11", BSL_OID_GLOBAL}, "STREET", BSL_CID_STREETADDRESS},
|
||||
{{3, "\125\4\12", BSL_OID_GLOBAL}, "O", BSL_CID_ORGANIZATIONNAME},
|
||||
{{3, "\125\4\13", BSL_OID_GLOBAL}, "OU", BSL_CID_ORGANIZATIONUNITNAME},
|
||||
{{3, "\125\4\14", BSL_OID_GLOBAL}, "title", BSL_CID_TITLE},
|
||||
{{3, "\125\4\52", BSL_OID_GLOBAL}, "GN", BSL_CID_GIVENNAME},
|
||||
{{3, "\125\4\53", BSL_OID_GLOBAL}, "initials", BSL_CID_INITIALS},
|
||||
{{3, "\125\4\54", BSL_OID_GLOBAL}, "generationQualifier", BSL_CID_GENERATIONQUALIFIER},
|
||||
{{3, "\125\4\56", BSL_OID_GLOBAL}, "dnQualifier", BSL_CID_DNQUALIFIER},
|
||||
{{3, "\125\4\101", BSL_OID_GLOBAL}, "pseudonym", BSL_CID_PSEUDONYM},
|
||||
{{10, "\11\222\46\211\223\362\54\144\1\31", BSL_OID_GLOBAL}, "DC", BSL_CID_DOMAINCOMPONENT},
|
||||
{{10, "\11\222\46\211\223\362\54\144\1\1", BSL_OID_GLOBAL}, "UID", BSL_CID_USERID},
|
||||
{{9, "\52\206\110\206\367\15\1\11\1", BSL_OID_GLOBAL}, "emailAddress", BSL_CID_EMAILADDRESS},
|
||||
|
||||
{{9, "\52\206\110\206\367\15\1\11\16", BSL_OID_GLOBAL}, "Requested Extensions", BSL_CID_REQ_EXTENSION},
|
||||
|
||||
{{9, "\52\206\110\206\367\15\1\7\1", BSL_OID_GLOBAL}, "data", BSL_CID_DATA},
|
||||
{{9, "\52\206\110\206\367\15\1\7\6", BSL_OID_GLOBAL}, "encryptedData", BSL_CID_ENCRYPTEDDATA},
|
||||
|
||||
{{9, "\52\206\110\206\367\15\1\11\24", BSL_OID_GLOBAL}, "friendlyName", BSL_CID_FRIENDLYNAME},
|
||||
{{9, "\52\206\110\206\367\15\1\11\25", BSL_OID_GLOBAL}, "localKeyId", BSL_CID_LOCALKEYID},
|
||||
{{10, "\52\206\110\206\367\15\1\11\26\1", BSL_OID_GLOBAL}, "x509Certificate", BSL_CID_X509CERTIFICATE},
|
||||
|
||||
{{11, "\52\206\110\206\367\15\1\14\12\1\1", BSL_OID_GLOBAL}, "keyBag", BSL_CID_KEYBAG},
|
||||
{{11, "\52\206\110\206\367\15\1\14\12\1\2", BSL_OID_GLOBAL}, "pkcs8shroudedkeyBag", BSL_CID_PKCS8SHROUDEDKEYBAG},
|
||||
{{11, "\52\206\110\206\367\15\1\14\12\1\3", BSL_OID_GLOBAL}, "certBag", BSL_CID_CERTBAG},
|
||||
{{11, "\52\206\110\206\367\15\1\14\12\1\4", BSL_OID_GLOBAL}, "crlBag", BSL_CID_CRLBAG},
|
||||
{{11, "\52\206\110\206\367\15\1\14\12\1\5", BSL_OID_GLOBAL}, "secretBag", BSL_CID_SECRETBAG},
|
||||
{{11, "\52\206\110\206\367\15\1\14\12\1\6", BSL_OID_GLOBAL}, "safeContent", BSL_CID_SAFECONTENT},
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
BslCid signId;
|
||||
BslCid asymId;
|
||||
BslCid hashId;
|
||||
} BslSignIdMap;
|
||||
|
||||
static BslSignIdMap g_signIdMap[] = {
|
||||
{BSL_CID_MD5WITHRSA, BSL_CID_RSA, BSL_CID_MD5},
|
||||
{BSL_CID_SHA1WITHRSA, BSL_CID_RSA, BSL_CID_SHA1},
|
||||
{BSL_CID_SHA224WITHRSAENCRYPTION, BSL_CID_RSA, BSL_CID_SHA224},
|
||||
{BSL_CID_SHA256WITHRSAENCRYPTION, BSL_CID_RSA, BSL_CID_SHA256},
|
||||
{BSL_CID_SHA384WITHRSAENCRYPTION, BSL_CID_RSA, BSL_CID_SHA384},
|
||||
{BSL_CID_SHA512WITHRSAENCRYPTION, BSL_CID_RSA, BSL_CID_SHA512},
|
||||
{BSL_CID_SM3WITHRSAENCRYPTION, BSL_CID_RSA, BSL_CID_SM3},
|
||||
{BSL_CID_ECDSAWITHSHA1, BSL_CID_ECDSA, BSL_CID_SHA1},
|
||||
{BSL_CID_ECDSAWITHSHA224, BSL_CID_ECDSA, BSL_CID_SHA224},
|
||||
{BSL_CID_ECDSAWITHSHA256, BSL_CID_ECDSA, BSL_CID_SHA256},
|
||||
{BSL_CID_ECDSAWITHSHA384, BSL_CID_ECDSA, BSL_CID_SHA384},
|
||||
{BSL_CID_ECDSAWITHSHA512, BSL_CID_ECDSA, BSL_CID_SHA512},
|
||||
{BSL_CID_SM2DSAWITHSM3, BSL_CID_SM2, BSL_CID_SM3},
|
||||
};
|
||||
|
||||
/**
|
||||
* RFC 5280: A.1. Explicitly Tagged Module, 1988 Syntax
|
||||
* -- Upper Bounds
|
||||
*/
|
||||
|
||||
static const BslAsn1StrInfo g_asn1StrTab[] = {
|
||||
{BSL_CID_COMMONNAME, 1, 64}, // ub-common-name INTEGER ::= 64
|
||||
{BSL_CID_SURNAME, 1, 40}, // ub-surname-length INTEGER ::= 40
|
||||
{BSL_CID_SERIALNUMBER, 1, 64}, // ub-serial-number INTEGER ::= 64
|
||||
{BSL_CID_COUNTRYNAME, 2, 2}, // ub-country-name-alpha-length INTEGER ::= 2
|
||||
{BSL_CID_LOCALITYNAME, 1, 128}, // ub-locality-name INTEGER ::= 128
|
||||
{BSL_CID_STATEORPROVINCENAME, 1, 128}, // ub-state-name INTEGER ::= 128
|
||||
{BSL_CID_STREETADDRESS, 1, -1}, // no limited
|
||||
{BSL_CID_ORGANIZATIONNAME, 1, 64}, // ub-organization-name INTEGER ::= 64
|
||||
{BSL_CID_ORGANIZATIONUNITNAME, 1, 64}, // ub-organizational-unit-name INTEGER ::= 64
|
||||
{BSL_CID_TITLE, 1, 64}, // ub-title INTEGER ::= 64
|
||||
{BSL_CID_GIVENNAME, 1, 32768}, // ub-name INTEGER ::= 32768
|
||||
{BSL_CID_INITIALS, 1, 32768}, // ub-name INTEGER ::= 32768
|
||||
{BSL_CID_GENERATIONQUALIFIER, 1, 32768}, // ub-name INTEGER ::= 32768
|
||||
{BSL_CID_DNQUALIFIER, 1, -1}, // no limited
|
||||
{BSL_CID_PSEUDONYM, 1, 128}, // ub-pseudonym INTEGER ::= 128
|
||||
{BSL_CID_DOMAINCOMPONENT, 1, -1, }, // no limited
|
||||
{BSL_CID_USERID, 1, 256}, // RFC1274
|
||||
};
|
||||
|
||||
BslCid BSL_OBJ_GetSignIdFromHashAndAsymId(BslCid asymAlg, BslCid hashAlg)
|
||||
{
|
||||
if (asymAlg == BSL_CID_UNKNOWN || hashAlg == BSL_CID_UNKNOWN) {
|
||||
return BSL_CID_UNKNOWN;
|
||||
}
|
||||
for (uint32_t i = 0; i < sizeof(g_signIdMap) / sizeof(g_signIdMap[0]); i++) {
|
||||
if (g_signIdMap[i].asymId == asymAlg && g_signIdMap[i].hashId == hashAlg) {
|
||||
return g_signIdMap[i].signId;
|
||||
}
|
||||
}
|
||||
return BSL_CID_UNKNOWN;
|
||||
}
|
||||
|
||||
uint32_t g_tableSize = (uint32_t)sizeof(g_oidTable)/sizeof(g_oidTable[0]);
|
||||
|
||||
static int32_t GetOidIndex(int32_t inputCid)
|
||||
{
|
||||
int32_t left = 0;
|
||||
int32_t right = g_tableSize - 1;
|
||||
while (left <= right) {
|
||||
int32_t mid = (right - left) / 2 + left;
|
||||
int32_t cid = g_oidTable[mid].cid;
|
||||
if (cid == inputCid) {
|
||||
return mid;
|
||||
} else if (cid > inputCid) {
|
||||
right = mid - 1;
|
||||
} else {
|
||||
left = mid + 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
BslCid BSL_OBJ_GetCIDFromOid(BslOidString *oid)
|
||||
{
|
||||
if (oid == NULL || oid->octs == NULL) {
|
||||
return BSL_CID_UNKNOWN;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < g_tableSize; i++) {
|
||||
if (g_oidTable[i].strOid.octetLen == oid->octetLen) {
|
||||
if (memcmp(g_oidTable[i].strOid.octs, oid->octs, oid->octetLen) == 0) {
|
||||
return g_oidTable[i].cid;
|
||||
}
|
||||
}
|
||||
}
|
||||
return BSL_CID_UNKNOWN;
|
||||
}
|
||||
|
||||
BslOidString *BSL_OBJ_GetOidFromCID(BslCid inputCid)
|
||||
{
|
||||
if (inputCid >= BSL_CID_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
int32_t index = GetOidIndex(inputCid);
|
||||
if (index == -1) {
|
||||
return NULL;
|
||||
}
|
||||
return &g_oidTable[index].strOid;
|
||||
}
|
||||
|
||||
const char *BSL_OBJ_GetOidNameFromOid(const BslOidString *oid)
|
||||
{
|
||||
if (oid == NULL || oid->octs == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < g_tableSize; i++) {
|
||||
if (g_oidTable[i].strOid.octetLen == oid->octetLen) {
|
||||
if (memcmp(g_oidTable[i].strOid.octs, oid->octs, oid->octetLen) == 0) {
|
||||
return g_oidTable[i].oidName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const BslAsn1StrInfo *BSL_OBJ_GetAsn1StrFromCid(BslCid cid)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(g_asn1StrTab) / sizeof(g_asn1StrTab[0]); i++) {
|
||||
if (cid == g_asn1StrTab[i].cid) {
|
||||
return &g_asn1StrTab[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
#ifndef BSL_PEM_INTERNAL_H
|
||||
#define BSL_PEM_INTERNAL_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_PEM
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BSL_PEM_CERT_BEGIN_STR "-----BEGIN CERTIFICATE-----"
|
||||
#define BSL_PEM_CERT_END_STR "-----END CERTIFICATE-----"
|
||||
|
||||
#define BSL_PEM_CRL_BEGIN_STR "-----BEGIN X509 CRL-----"
|
||||
#define BSL_PEM_CRL_END_STR "-----END X509 CRL-----"
|
||||
|
||||
#define BSL_PEM_PUB_KEY_BEGIN_STR "-----BEGIN PUBLIC KEY-----"
|
||||
#define BSL_PEM_PUB_KEY_END_STR "-----END PUBLIC KEY-----"
|
||||
|
||||
#define BSL_PEM_RSA_PUB_KEY_BEGIN_STR "-----BEGIN RSA PUBLIC KEY-----"
|
||||
#define BSL_PEM_RSA_PUB_KEY_END_STR "-----END RSA PUBLIC KEY-----"
|
||||
|
||||
#define BSL_PEM_RSA_PIR_KEY_BEGIN_STR "-----BEGIN RSA PRIVATE KEY-----"
|
||||
#define BSL_PEM_RSA_PIR_KEY_END_STR "-----END RSA PRIVATE KEY-----"
|
||||
|
||||
/** rfc5915 section 4 */
|
||||
#define BSL_PEM_EC_PIR_KEY_BEGIN_STR "-----BEGIN EC PRIVATE KEY-----"
|
||||
#define BSL_PEM_EC_PIR_KEY_END_STR "-----END EC PRIVATE KEY-----"
|
||||
|
||||
/** rfc5958 section 5 */
|
||||
#define BSL_PEM_PIR_KEY_BEGIN_STR "-----BEGIN PRIVATE KEY-----"
|
||||
#define BSL_PEM_PIR_KEY_END_STR "-----END PRIVATE KEY-----"
|
||||
|
||||
/** rfc5958 section 5 */
|
||||
#define BSL_PEM_P8_PRI_KEY_BEGIN_STR "-----BEGIN ENCRYPTED PRIVATE KEY-----"
|
||||
#define BSL_PEM_P8_PRI_KEY_END_STR "-----END ENCRYPTED PRIVATE KEY-----"
|
||||
|
||||
#define BSL_PEM_CERT_REQ_BEGIN_STR "-----BEGIN CERTIFICATE REQUEST-----"
|
||||
#define BSL_PEM_CERT_REQ_END_STR "-----END CERTIFICATE REQUEST-----"
|
||||
|
||||
typedef struct {
|
||||
const char *head;
|
||||
const char *tail;
|
||||
} BSL_PEM_Symbol;
|
||||
|
||||
int32_t BSL_PEM_EncodeAsn1ToPem(uint8_t *asn1Encode, uint32_t asn1Len, BSL_PEM_Symbol *symbol,
|
||||
char **encode, uint32_t *encodeLen);
|
||||
|
||||
/* encode must end in '\0' */
|
||||
int32_t BSL_PEM_ParsePem2Asn1(char **encode, uint32_t *encodeLen, BSL_PEM_Symbol *symbol, uint8_t **asn1Encode,
|
||||
uint32_t *asn1Len);
|
||||
|
||||
/* encode must end in '\0' */
|
||||
bool BSL_PEM_IsPemFormat(char *encode, uint32_t encodeLen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* HITLS_BSL_PEM */
|
||||
#endif /* BSL_PEM_INTERNAL_H */
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_PEM
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "securec.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_err_internal.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_base64_internal.h"
|
||||
#include "bsl_base64.h"
|
||||
#include "bsl_pem_local.h"
|
||||
#include "bsl_pem_internal.h"
|
||||
|
||||
#define PEM_LINE_LEN 64
|
||||
|
||||
int32_t BSL_PEM_GetPemRealEncode(char **encode, uint32_t *encodeLen, BSL_PEM_Symbol *symbol, char **realEncode,
|
||||
uint32_t *realLen)
|
||||
{
|
||||
uint32_t headLen = strlen(symbol->head);
|
||||
uint32_t tailLen = strlen(symbol->tail);
|
||||
if (*encodeLen < headLen + tailLen) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_PEM_INVALID);
|
||||
return BSL_PEM_INVALID;
|
||||
}
|
||||
if (!BSL_PEM_IsPemFormat(*encode, *encodeLen)) {
|
||||
return BSL_PEM_INVALID;
|
||||
}
|
||||
char *begin = strstr(*encode, symbol->head);
|
||||
if (begin == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_PEM_SYMBOL_NOT_FOUND);
|
||||
return BSL_PEM_SYMBOL_NOT_FOUND;
|
||||
}
|
||||
char *end = strstr(begin, symbol->tail);
|
||||
if (end == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_PEM_SYMBOL_NOT_FOUND);
|
||||
return BSL_PEM_SYMBOL_NOT_FOUND;
|
||||
}
|
||||
*realEncode = begin + headLen;
|
||||
*realLen = end - *realEncode;
|
||||
*encodeLen -= (end - *encode + tailLen);
|
||||
*encode = end + tailLen;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
// Obtain asn1 raw data
|
||||
int32_t BSL_PEM_GetAsn1Encode(const char *encode, const uint32_t encodeLen, uint8_t **asn1Encode,
|
||||
uint32_t *asn1Len)
|
||||
{
|
||||
uint32_t len = BSL_BASE64_DEC_ENOUGH_LEN(encodeLen);
|
||||
uint8_t *asn1 = BSL_SAL_Malloc(len);
|
||||
if (asn1 == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
|
||||
return BSL_MALLOC_FAIL;
|
||||
}
|
||||
int32_t ret = BSL_BASE64_Decode(encode, encodeLen, asn1, &len);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(ret);
|
||||
BSL_SAL_Free(asn1);
|
||||
return ret;
|
||||
}
|
||||
*asn1Encode = asn1;
|
||||
*asn1Len = len;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static void PemFormatBase64(char *src, uint32_t srcLen, char **des)
|
||||
{
|
||||
uint32_t len = srcLen;
|
||||
char *tmp = *des;
|
||||
while (len > PEM_LINE_LEN) {
|
||||
*tmp++ = '\n';
|
||||
(void)memcpy_s(tmp, PEM_LINE_LEN, src, PEM_LINE_LEN);
|
||||
tmp += PEM_LINE_LEN;
|
||||
src += PEM_LINE_LEN;
|
||||
len -= PEM_LINE_LEN;
|
||||
}
|
||||
*tmp++ = '\n';
|
||||
(void)memcpy_s(tmp, len, src, len);
|
||||
tmp += len;
|
||||
*tmp++ = '\n';
|
||||
*des = tmp;
|
||||
}
|
||||
|
||||
int32_t BSL_PEM_EncodeAsn1ToPem(uint8_t *asn1Encode, uint32_t asn1Len, BSL_PEM_Symbol *symbol,
|
||||
char **encode, uint32_t *encodeLen)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t headLen = (uint32_t)strlen(symbol->head);
|
||||
uint32_t tailLen = (uint32_t)strlen(symbol->tail);
|
||||
uint32_t len = BSL_BASE64_ENC_ENOUGH_LEN(asn1Len);
|
||||
char *buff = BSL_SAL_Malloc(len);
|
||||
if (buff == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
|
||||
return BSL_MALLOC_FAIL;
|
||||
}
|
||||
char *tmp = buff;
|
||||
char *res = NULL;
|
||||
do {
|
||||
ret = BSL_BASE64_Encode(asn1Encode, asn1Len, tmp, &len);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(ret);
|
||||
break;
|
||||
}
|
||||
uint32_t line = (len + PEM_LINE_LEN - 1) / PEM_LINE_LEN;
|
||||
uint32_t sumLen = line + len + headLen + tailLen + 3; // 3: \n + \n +\0
|
||||
res = BSL_SAL_Malloc(sumLen);
|
||||
if (res == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
|
||||
ret = BSL_MALLOC_FAIL;
|
||||
break;
|
||||
}
|
||||
char *resTmp = res;
|
||||
(void)memcpy_s(resTmp, headLen, symbol->head, headLen);
|
||||
resTmp += headLen;
|
||||
PemFormatBase64(tmp, len, &resTmp);
|
||||
(void)memcpy_s(resTmp, tailLen, symbol->tail, tailLen);
|
||||
resTmp += tailLen;
|
||||
*resTmp++ = '\n';
|
||||
*resTmp++ = '\0';
|
||||
*encode = res;
|
||||
*encodeLen = sumLen - 1;
|
||||
BSL_SAL_FREE(buff);
|
||||
return BSL_SUCCESS;
|
||||
} while (0);
|
||||
BSL_SAL_FREE(buff);
|
||||
BSL_SAL_FREE(res);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_PEM_ParsePem2Asn1(char **encode, uint32_t *encodeLen, BSL_PEM_Symbol *symbol, uint8_t **asn1Encode,
|
||||
uint32_t *asn1Len)
|
||||
{
|
||||
char *nextEncode = *encode;
|
||||
uint32_t nextEncodeLen = *encodeLen;
|
||||
char *realEncode = NULL;
|
||||
uint32_t realLen;
|
||||
|
||||
int32_t ret = BSL_PEM_GetPemRealEncode(&nextEncode, &nextEncodeLen, symbol, &realEncode, &realLen);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = BSL_PEM_GetAsn1Encode(realEncode, realLen, asn1Encode, asn1Len);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(ret);
|
||||
return ret;
|
||||
}
|
||||
*encode = nextEncode;
|
||||
*encodeLen = nextEncodeLen;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* reference rfc7468
|
||||
* Textual encoding begins with a line comprising "-----BEGIN ", a label, and "-----",
|
||||
* and ends with a line comprising "-----END ", a label, and "-----".
|
||||
*/
|
||||
bool BSL_PEM_IsPemFormat(char *encode, uint32_t encodeLen)
|
||||
{
|
||||
if (encode == NULL || encodeLen < BSL_PEM_BEGIN_STR_LEN + BSL_PEM_END_STR_LEN
|
||||
+ BSL_PEM_SHORT_DASH_STR_LEN) {
|
||||
return false;
|
||||
}
|
||||
// match "-----BEGIN"
|
||||
char *begin = strstr(encode, BSL_PEM_BEGIN_STR);
|
||||
if (begin == NULL) {
|
||||
return false;
|
||||
}
|
||||
char *tmp = (char *)encode + BSL_PEM_BEGIN_STR_LEN;
|
||||
// match "-----"
|
||||
begin = strstr(tmp, BSL_PEM_SHORT_DASH_STR);
|
||||
if (begin == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
tmp = begin + BSL_PEM_SHORT_DASH_STR_LEN;
|
||||
|
||||
// match "-----END"
|
||||
begin = strstr(tmp, BSL_PEM_END_STR);
|
||||
if (begin == NULL) {
|
||||
return false;
|
||||
}
|
||||
tmp = begin + BSL_PEM_END_STR_LEN;
|
||||
|
||||
// match "-----"
|
||||
if (strstr(tmp, BSL_PEM_SHORT_DASH_STR) == NULL) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* HITLS_BSL_PEM */
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef BSL_PEM_LOCAL_H
|
||||
#define BSL_PEM_LOCAL_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_PEM
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BSL_PEM_BEGIN_STR "-----BEGIN"
|
||||
#define BSL_PEM_BEGIN_STR_LEN 10
|
||||
#define BSL_PEM_END_STR "-----END"
|
||||
#define BSL_PEM_END_STR_LEN 8
|
||||
#define BSL_PEM_SHORT_DASH_STR "-----"
|
||||
#define BSL_PEM_SHORT_DASH_STR_LEN 5
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* HITLS_BSL_PEM */
|
||||
#endif
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef SAL_ATOMIC_H
|
||||
#define SAL_ATOMIC_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_errno.h"
|
||||
|
||||
/* The value of __STDC_VERSION__ is determined by the compilation option -std.
|
||||
The atomic API is provided only when -std=gnu11 is used. */
|
||||
#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
|
||||
#include <stdatomic.h>
|
||||
#define SAL_HAVE_C11_ATOMICS
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
int BSL_SAL_AtomicAdd(int *val, int amount, int *ref, BSL_SAL_ThreadLockHandle lock);
|
||||
|
||||
/* Atom operation mode 1, which uses the function provided by C11. Only the int type is considered.
|
||||
* ATOMIC_INT_LOCK_FREE: If the value is 1, the operation MAY BE lock-free operation.
|
||||
* ATOMIC_INT_LOCK_FREE: If the value is 2, it's the lock-free operation.
|
||||
* memory_order_relaxed only ensures the atomicity of the current operation
|
||||
* and does not consider the synchronization between threads.
|
||||
*/
|
||||
#if defined(SAL_HAVE_C11_ATOMICS) && defined(ATOMIC_INT_LOCK_FREE) && ATOMIC_INT_LOCK_FREE > 0
|
||||
#define SAL_USE_ATOMICS_LIB_FUNC
|
||||
typedef struct {
|
||||
atomic_int count;
|
||||
} BSL_SAL_RefCount;
|
||||
|
||||
static inline int BSL_SAL_AtomicUpReferences(BSL_SAL_RefCount *references, int *ret)
|
||||
{
|
||||
*ret = atomic_fetch_add_explicit(&(references->count), 1, memory_order_relaxed) + 1;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int BSL_SAL_AtomicDownReferences(BSL_SAL_RefCount *references, int *ret)
|
||||
{
|
||||
*ret = atomic_fetch_sub_explicit(&(references->count), 1, memory_order_relaxed) - 1;
|
||||
if (*ret == 0) {
|
||||
atomic_thread_fence(memory_order_acquire);
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
/* Atom operation mode 2, using the function provided by the GCC. */
|
||||
#elif defined(__GNUC__) && defined(__ATOMIC_RELAXED) && __GCC_ATOMIC_INT_LOCK_FREE > 0
|
||||
#define SAL_USE_ATOMICS_LIB_FUNC
|
||||
typedef struct {
|
||||
int count;
|
||||
} BSL_SAL_RefCount;
|
||||
|
||||
static inline int BSL_SAL_AtomicUpReferences(BSL_SAL_RefCount *references, int *ret)
|
||||
{
|
||||
*ret = __atomic_fetch_add(&(references->count), 1, __ATOMIC_RELAXED) + 1;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int BSL_SAL_AtomicDownReferences(BSL_SAL_RefCount *references, int *ret)
|
||||
{
|
||||
*ret = __atomic_fetch_sub(&(references->count), 1, __ATOMIC_RELAXED) - 1;
|
||||
if (*ret == 0) {
|
||||
const int type = __ATOMIC_ACQUIRE;
|
||||
__atomic_thread_fence(type);
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
// Atom operation mode 3, using read/write locks.
|
||||
#else
|
||||
typedef struct {
|
||||
int count;
|
||||
BSL_SAL_ThreadLockHandle lock;
|
||||
} BSL_SAL_RefCount;
|
||||
|
||||
static inline int BSL_SAL_AtomicUpReferences(BSL_SAL_RefCount *references, int *ret)
|
||||
{
|
||||
return BSL_SAL_AtomicAdd(&(references->count), 1, ret, references->lock);
|
||||
}
|
||||
|
||||
static inline int BSL_SAL_AtomicDownReferences(BSL_SAL_RefCount *references, int *ret)
|
||||
{
|
||||
return BSL_SAL_AtomicAdd(&(references->count), -1, ret, references->lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SAL_USE_ATOMICS_LIB_FUNC
|
||||
static inline int BSL_SAL_ReferencesInit(BSL_SAL_RefCount *references)
|
||||
{
|
||||
references->count = 1;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static inline void BSL_SAL_ReferencesFree(BSL_SAL_RefCount *references)
|
||||
{
|
||||
(void)references;
|
||||
return;
|
||||
}
|
||||
#else
|
||||
static inline int BSL_SAL_ReferencesInit(BSL_SAL_RefCount *references)
|
||||
{
|
||||
references->count = 1;
|
||||
return BSL_SAL_ThreadLockNew(&(references->lock));
|
||||
}
|
||||
|
||||
static inline void BSL_SAL_ReferencesFree(BSL_SAL_RefCount *references)
|
||||
{
|
||||
BSL_SAL_ThreadLockFree(references->lock);
|
||||
references->lock = NULL;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // SAL_ATOMIC_H
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef SAL_FILE_H
|
||||
#define SAL_FILE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef HITLS_BSL_SAL_FILE
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup bsl_sal
|
||||
* @brief Reads the specified file into the buff
|
||||
*
|
||||
* Reads the specified file into the buff
|
||||
*
|
||||
* @attention None.
|
||||
* @param path [IN] specified file.
|
||||
* @param buff [OUT] return the read memory.
|
||||
* @param len [OUT] return the read memory len.
|
||||
* @retval if the operation is successful, BSL_SUCCESS is returned, for other errors, see bsl_error.h
|
||||
*/
|
||||
int32_t BSL_SAL_ReadFile(const char *path, uint8_t **buff, uint32_t *len);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_sal
|
||||
* @brief Writes the buff to the specified file
|
||||
*
|
||||
* Writes the buff to the specified file
|
||||
*
|
||||
* @attention None.
|
||||
* @param path [IN] specified file.
|
||||
* @param buff [IN] the write memory.
|
||||
* @param len [IN] the write memory len.
|
||||
* @retval if the operation is successful, BSL_SUCCESS is returned, for other errors, see bsl_error.h
|
||||
*/
|
||||
int32_t BSL_SAL_WriteFile(const char *path, const uint8_t *buff, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HITLS_BSL_SAL_FILE */
|
||||
|
||||
#endif // SAL_FILE_H
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef SAL_NET_H
|
||||
#define SAL_NET_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_SAL_NET
|
||||
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_BSL_UIO_SCTP
|
||||
#include <netinet/sctp.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int32_t BSL_SAL_Write(int32_t fd, const void *buf, uint32_t len, int32_t *err);
|
||||
|
||||
int32_t BSL_SAL_Read(int32_t fd, void *buf, uint32_t len, int32_t *err);
|
||||
|
||||
int32_t BSL_SAL_SetSockopt(int32_t sockId, int32_t level, int32_t name, const void *val, uint32_t len);
|
||||
|
||||
int32_t BSL_SAL_GetSockopt(int32_t sockId, int32_t level, int32_t name, void *val, uint32_t *len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* HITLS_BSL_SAL_NET */
|
||||
|
||||
#endif // SAL_NET_H
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef SAL_TIME_H
|
||||
#define SAL_TIME_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_SAL_TIME
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "bsl_sal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BSL_TIME_CMP_ERROR 0U /* The comparison between two dates is incorrect. */
|
||||
#define BSL_TIME_CMP_EQUAL 1U /* The two dates are the same. */
|
||||
#define BSL_TIME_DATE_BEFORE 2U /* The first date is earlier than the second date */
|
||||
#define BSL_TIME_DATE_AFTER 3U /* The first date is later than the second date. */
|
||||
|
||||
#define BSL_TIME_YEAR_START 1900U
|
||||
#define BSL_TIME_SYSTEM_EPOCH_YEAR 1970U
|
||||
#define BSL_TIME_DAY_PER_NONLEAP_YEAR 365U
|
||||
|
||||
#define BSL_TIME_BIG_MONTH_DAY 31U
|
||||
#define BSL_TIME_SMALL_MONTH_DAY 30U
|
||||
#define BSL_TIME_LEAP_FEBRUARY_DAY 29U
|
||||
#define BSL_TIME_NOLEAP_FEBRUARY_DAY 28U
|
||||
|
||||
#define BSL_MONTH_JAN 1U /* January */
|
||||
#define BSL_MONTH_FEB 2U /* February */
|
||||
#define BSL_MONTH_MAR 3U /* March */
|
||||
#define BSL_MONTH_APR 4U /* April */
|
||||
#define BSL_MONTH_MAY 5U /* May */
|
||||
#define BSL_MONTH_JUN 6U /* June */
|
||||
#define BSL_MONTH_JUL 7U /* July */
|
||||
#define BSL_MONTH_AUG 8U /* August */
|
||||
#define BSL_MONTH_SEM 9U /* September */
|
||||
#define BSL_MONTH_OCT 10U /* October */
|
||||
#define BSL_MONTH_NOV 11U /* November */
|
||||
#define BSL_MONTH_DEC 12U /* December */
|
||||
|
||||
#define BSL_TIME_TICKS_PER_SECOND_DEFAULT 100U
|
||||
#define BSL_SECOND_TRANSFER_RATIO 1000U /* conversion ratio of microseconds -> milliseconds -> seconds */
|
||||
|
||||
#define BSL_UTCTIME_MAX 2005949145599L /* UTC time corresponding to December 31, 65535 23:59:59 */
|
||||
|
||||
bool BSL_IsLeapYear(uint32_t year);
|
||||
|
||||
/**
|
||||
* @brief Obtain the date in string format.
|
||||
* @param dateTime [IN] Pointer to the date structure to be converted into a string.
|
||||
* @param timeStr [OUT] Pointer to the date string buffer.
|
||||
* @param len [IN] Date string buffer length, which must be greater than 26.
|
||||
* @return BSL_SUCCESS is successfully executed.
|
||||
* BSL_INTERNAL_EXCEPTION Execution Failure
|
||||
*/
|
||||
uint32_t BSL_DateToStrConvert(const BSL_TIME *dateTime, char *timeStr, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Add the time.
|
||||
* @param date [IN]
|
||||
* @param us [IN]
|
||||
* @return BSL_SUCCESS is successfully executed.
|
||||
* For other failures, see BSL_SAL_DateToUtcTimeConvert and BSL_SAL_UtcTimeToDateConvert.
|
||||
*/
|
||||
uint32_t BSL_DateTimeAddUs(BSL_TIME *dateR, const BSL_TIME *dateA, uint32_t us);
|
||||
|
||||
/**
|
||||
* @brief Check whether the time format is correct.
|
||||
* @param dateTime [IN] Time to be checked
|
||||
* @return true The time format is correct.
|
||||
* false incorrect
|
||||
*/
|
||||
bool BSL_DateTimeCheck(const BSL_TIME *dateTime);
|
||||
|
||||
void BSL_SysTimeFuncUnReg(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_BSL_SAL_TIME */
|
||||
|
||||
#endif // SAL_TIME_H
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#if defined(HITLS_BSL_SAL_LINUX) && defined(HITLS_BSL_SAL_FILE)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_sal.h"
|
||||
|
||||
int32_t SAL_FileOpen(bsl_sal_file_handle *stream, const char *path, const char *mode)
|
||||
{
|
||||
bsl_sal_file_handle temp = NULL;
|
||||
|
||||
if (path == NULL || path[0] == 0 || mode == NULL || stream == NULL) {
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
|
||||
temp = (bsl_sal_file_handle)fopen(path, mode);
|
||||
if (temp == NULL) {
|
||||
return BSL_SAL_ERR_FILE_OPEN;
|
||||
}
|
||||
|
||||
(*stream) = temp;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t SAL_FileRead(bsl_sal_file_handle stream, void *buffer, size_t size, size_t num, size_t *len)
|
||||
{
|
||||
if (stream == NULL || buffer == NULL || len == NULL) {
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
*len = fread(buffer, size, num, stream);
|
||||
if (*len != num) {
|
||||
return feof(stream) != 0 ? BSL_SUCCESS : BSL_SAL_ERR_FILE_READ;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t SAL_FileWrite(bsl_sal_file_handle stream, const void *buffer, size_t size, size_t num)
|
||||
{
|
||||
if (stream == NULL || buffer == NULL) {
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
size_t ret = fwrite(buffer, size, num, stream);
|
||||
|
||||
return ret == num ? BSL_SUCCESS : BSL_SAL_ERR_FILE_WRITE;
|
||||
}
|
||||
|
||||
void SAL_FileClose(bsl_sal_file_handle stream)
|
||||
{
|
||||
(void)fclose(stream);
|
||||
}
|
||||
|
||||
int32_t SAL_FileLength(const char *path, size_t *len)
|
||||
{
|
||||
int32_t ret;
|
||||
long tmp;
|
||||
bsl_sal_file_handle stream = NULL;
|
||||
|
||||
if (path == NULL || len == NULL) {
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
|
||||
ret = BSL_SAL_FileOpen(&stream, path, "rb");
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return BSL_SAL_ERR_FILE_LENGTH;
|
||||
}
|
||||
|
||||
ret = fseek(stream, 0, SEEK_END);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_SAL_FileClose(stream);
|
||||
return BSL_SAL_ERR_FILE_LENGTH;
|
||||
}
|
||||
|
||||
tmp = ftell(stream);
|
||||
if (tmp < 0) {
|
||||
BSL_SAL_FileClose(stream);
|
||||
return BSL_SAL_ERR_FILE_LENGTH;
|
||||
}
|
||||
|
||||
*len = (size_t)tmp;
|
||||
|
||||
BSL_SAL_FileClose(stream);
|
||||
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include "hitls_build.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_sal.h"
|
||||
|
||||
#if defined(HITLS_BSL_SAL_LINUX) && defined(HITLS_BSL_SAL_LOCK)
|
||||
|
||||
// Used for DEFAULT lock implementation
|
||||
typedef struct {
|
||||
pthread_rwlock_t rwlock;
|
||||
} BslOsalRWLock;
|
||||
|
||||
int32_t SAL_RwLockNew(BSL_SAL_ThreadLockHandle *lock)
|
||||
{
|
||||
if (lock == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
BslOsalRWLock *newLock = (BslOsalRWLock *)BSL_SAL_Calloc(1, sizeof(BslOsalRWLock));
|
||||
if (newLock == NULL) {
|
||||
return BSL_MALLOC_FAIL;
|
||||
}
|
||||
|
||||
if (pthread_rwlock_init(&newLock->rwlock, (const pthread_rwlockattr_t *)NULL) != 0) {
|
||||
BSL_SAL_FREE(newLock);
|
||||
return BSL_SAL_ERR_UNKNOWN;
|
||||
}
|
||||
*lock = newLock;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t SAL_RwReadLock(BSL_SAL_ThreadLockHandle rwLock)
|
||||
{
|
||||
BslOsalRWLock *lock = (BslOsalRWLock *)rwLock;
|
||||
if (lock == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
if (pthread_rwlock_rdlock(&lock->rwlock) != 0) {
|
||||
return BSL_SAL_ERR_UNKNOWN;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t SAL_RwWriteLock(BSL_SAL_ThreadLockHandle rwLock)
|
||||
{
|
||||
BslOsalRWLock *lock = (BslOsalRWLock *)rwLock;
|
||||
if (lock == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
if (pthread_rwlock_wrlock(&lock->rwlock) != 0) {
|
||||
return BSL_SAL_ERR_UNKNOWN;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t SAL_RwUnlock(BSL_SAL_ThreadLockHandle rwLock)
|
||||
{
|
||||
BslOsalRWLock *lock = (BslOsalRWLock *)rwLock;
|
||||
if (lock == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
|
||||
if (pthread_rwlock_unlock(&lock->rwlock) != 0) {
|
||||
return BSL_SAL_ERR_UNKNOWN;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
void SAL_RwLockFree(BSL_SAL_ThreadLockHandle rwLock)
|
||||
{
|
||||
BslOsalRWLock *lock = (BslOsalRWLock *)rwLock;
|
||||
if (lock != NULL) {
|
||||
(void)pthread_rwlock_destroy(&(lock->rwlock));
|
||||
BSL_SAL_FREE(lock);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_BSL_SAL_LINUX) && defined(HITLS_BSL_SAL_THREAD)
|
||||
uint64_t SAL_GetPid(void)
|
||||
{
|
||||
// By default, gettid is not used to obtain the global tid corresponding to the thread
|
||||
// because other thread functions use the pthread library.
|
||||
// Use pthread_self to obtain the PID used by pthread_create in this process.
|
||||
// However, the pids of the parent and child processes may be the same.
|
||||
return (uint64_t)pthread_self();
|
||||
}
|
||||
|
||||
int32_t SAL_PthreadRunOnce(uint32_t *onceControl, BSL_SAL_ThreadInitRoutine initFunc)
|
||||
{
|
||||
if (onceControl == NULL || initFunc == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
|
||||
pthread_once_t *tmpOnce = (pthread_once_t *)onceControl;
|
||||
if (pthread_once(tmpOnce, initFunc) != 0) {
|
||||
return BSL_SAL_ERR_UNKNOWN;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_ThreadCreate(BSL_SAL_ThreadId *thread, void *(*startFunc)(void *), void *arg)
|
||||
{
|
||||
if (thread == NULL || startFunc == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
int32_t ret = pthread_create((pthread_t *)thread, NULL, startFunc, arg);
|
||||
if (ret != 0) {
|
||||
return BSL_SAL_ERR_UNKNOWN;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
void BSL_SAL_ThreadClose(BSL_SAL_ThreadId thread)
|
||||
{
|
||||
if (thread == NULL) {
|
||||
return;
|
||||
}
|
||||
(void)pthread_join((pthread_t)(uintptr_t)thread, NULL);
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_CreateCondVar(BSL_SAL_CondVar *condVar)
|
||||
{
|
||||
if (condVar == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
pthread_cond_t *cond = (pthread_cond_t *)BSL_SAL_Malloc(sizeof(pthread_cond_t));
|
||||
if (cond == NULL) {
|
||||
return BSL_MALLOC_FAIL;
|
||||
}
|
||||
if (pthread_cond_init(cond, NULL) != 0) {
|
||||
BSL_SAL_FREE(cond);
|
||||
return BSL_SAL_ERR_UNKNOWN;
|
||||
}
|
||||
*condVar = cond;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_CondSignal(BSL_SAL_CondVar condVar)
|
||||
{
|
||||
if (condVar == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
if (pthread_cond_signal(condVar) != 0) {
|
||||
return BSL_SAL_ERR_UNKNOWN;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
#define SAL_SECS_IN_NS 1000000000 // 1s = 1000000000ns
|
||||
#define SAL_SECS_IN_MS 1000 // 1s = 1000ms
|
||||
#define SAL_MS_IN_NS 1000000 // 1ms = 1000000ns
|
||||
|
||||
int32_t BSL_SAL_CondTimedwaitMs(BSL_SAL_Mutex condMutex, BSL_SAL_CondVar condVar, int32_t timeout)
|
||||
{
|
||||
struct timespec stm = {0};
|
||||
struct timespec etm = {0};
|
||||
long int endNs; // nanosecond
|
||||
long int endSecs; // second
|
||||
if (condMutex == NULL || condVar == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
pthread_mutex_lock(condMutex);
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &stm);
|
||||
endSecs = stm.tv_sec + timeout / SAL_SECS_IN_MS;
|
||||
endNs = stm.tv_nsec + (timeout % SAL_SECS_IN_MS) * SAL_MS_IN_NS;
|
||||
endSecs += endNs / SAL_SECS_IN_NS;
|
||||
endNs %= SAL_SECS_IN_NS;
|
||||
etm.tv_sec = endSecs;
|
||||
etm.tv_nsec = endNs;
|
||||
|
||||
int32_t ret = pthread_cond_timedwait(condVar, condMutex, &etm);
|
||||
pthread_mutex_unlock(condMutex);
|
||||
if (ret != 0) {
|
||||
return BSL_SAL_ERR_UNKNOWN;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_DeleteCondVar(BSL_SAL_CondVar condVar)
|
||||
{
|
||||
if (condVar == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
int32_t ret = pthread_cond_destroy((pthread_cond_t *)condVar);
|
||||
BSL_SAL_FREE(condVar);
|
||||
if (ret != 0) {
|
||||
return BSL_SAL_ERR_UNKNOWN;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#if defined(HITLS_BSL_SAL_LINUX) && defined(HITLS_BSL_SAL_MEM)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void *SAL_MallocImpl(uint32_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void SAL_FreeImpl(void *value)
|
||||
{
|
||||
if (value == NULL) {
|
||||
return;
|
||||
}
|
||||
free(value);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#if defined(HITLS_BSL_SAL_LINUX) && defined(HITLS_BSL_SAL_NET)
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "sal_net.h"
|
||||
|
||||
int32_t SAL_Write(int32_t fd, const void *buf, uint32_t len, int32_t *err)
|
||||
{
|
||||
if (err == NULL) {
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
int32_t ret = (int32_t)write(fd, buf, len);
|
||||
if (ret < 0) {
|
||||
*err = errno;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t SAL_Read(int32_t fd, void *buf, uint32_t len, int32_t *err)
|
||||
{
|
||||
if (err == NULL) {
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
int32_t ret = (int32_t)read(fd, buf, len);
|
||||
if (ret < 0) {
|
||||
*err = errno;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t SAL_Socket(int32_t af, int32_t type, int32_t protocol)
|
||||
{
|
||||
return (int32_t)socket(af, type, protocol);
|
||||
}
|
||||
|
||||
int32_t SAL_SockClose(int32_t sockId)
|
||||
{
|
||||
if (close((int32_t)(long)sockId) != 0) {
|
||||
return BSL_SAL_ERR_NET_SOCKCLOSE;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t SAL_SetSockopt(int32_t sockId, int32_t level, int32_t name, const void *val, uint32_t len)
|
||||
{
|
||||
if (setsockopt((int32_t)sockId, level, name, (char *)(uintptr_t)val, (socklen_t)len) != 0) {
|
||||
return BSL_SAL_ERR_NET_SETSOCKOPT;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t SAL_GetSockopt(int32_t sockId, int32_t level, int32_t name, void *val, uint32_t *len)
|
||||
{
|
||||
if (getsockopt((int32_t)sockId, level, name, val, (socklen_t *)len) != 0) {
|
||||
return BSL_SAL_ERR_NET_GETSOCKOPT;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t SAL_SockListen(int32_t sockId, int32_t backlog)
|
||||
{
|
||||
if (listen(sockId, backlog) != 0) {
|
||||
return BSL_SAL_ERR_NET_LISTEN;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t SAL_SockBind(int32_t sockId, BSL_SAL_SockAddr addr, size_t len)
|
||||
{
|
||||
if (bind(sockId, (struct sockaddr *)addr, (socklen_t)len) != 0) {
|
||||
return BSL_SAL_ERR_NET_BIND;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t SAL_SockConnect(int32_t sockId, BSL_SAL_SockAddr addr, size_t len)
|
||||
{
|
||||
if (connect(sockId, (struct sockaddr *)addr, (socklen_t)len) != 0) {
|
||||
return BSL_SAL_ERR_NET_CONNECT;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t SAL_SockSend(int32_t sockId, const void *msg, size_t len, int32_t flags)
|
||||
{
|
||||
return (int32_t)send(sockId, (char *)msg, len, flags);
|
||||
}
|
||||
|
||||
int32_t SAL_SockRecv(int32_t sockfd, void *buff, size_t len, int32_t flags)
|
||||
{
|
||||
return (int32_t)recv(sockfd, (char *)buff, len, flags);
|
||||
}
|
||||
|
||||
int32_t SAL_Select(int32_t nfds, void *readfds, void *writefds, void *exceptfds, void *timeout)
|
||||
{
|
||||
return select(nfds, (fd_set *)readfds, (fd_set *)writefds, (fd_set *)exceptfds, (struct timeval *)timeout);
|
||||
}
|
||||
|
||||
int32_t SAL_Ioctlsocket(int32_t sockId, long cmd, unsigned long *arg)
|
||||
{
|
||||
if (ioctl(sockId, (unsigned long)cmd, arg) != 0) {
|
||||
return BSL_SAL_ERR_NET_IOCTL;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t SAL_SockGetLastSocketError(void)
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#if defined(HITLS_BSL_SAL_LINUX) && defined(HITLS_BSL_SAL_STR)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bsl_errno.h"
|
||||
|
||||
int32_t BSL_SAL_StrcaseCmp(const char *str1, const char *str2)
|
||||
{
|
||||
if (str1 == NULL || str2 == NULL) {
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
return strcasecmp(str1, str2);
|
||||
}
|
||||
|
||||
void *BSL_SAL_Memchr(const char *str, int32_t character, size_t count)
|
||||
{
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return memchr(str, character, count);
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_Atoi(const char *str)
|
||||
{
|
||||
if (str == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return atoi(str);
|
||||
}
|
||||
|
||||
uint32_t BSL_SAL_Strnlen(const char *string, uint32_t count)
|
||||
{
|
||||
uint32_t n;
|
||||
const char *pscTemp = string;
|
||||
if (pscTemp == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (n = 0; (n < count) && (*pscTemp != '\0'); n++) {
|
||||
pscTemp++;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#if defined(HITLS_BSL_SAL_LINUX) && defined(HITLS_BSL_SAL_TIME)
|
||||
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
#include "bsl_sal.h"
|
||||
#include "sal_time.h"
|
||||
#include "bsl_errno.h"
|
||||
|
||||
int64_t TIME_GetSysTime(void)
|
||||
{
|
||||
return (int64_t)time(NULL);
|
||||
}
|
||||
|
||||
uint32_t TIME_DateToStrConvert(const BSL_TIME *dateTime, char *timeStr, size_t len)
|
||||
{
|
||||
struct tm timeStruct = {0};
|
||||
timeStruct.tm_year = (int32_t)dateTime->year - (int32_t)BSL_TIME_YEAR_START;
|
||||
timeStruct.tm_mon = (int32_t)dateTime->month - 1;
|
||||
timeStruct.tm_mday = (int32_t)dateTime->day;
|
||||
timeStruct.tm_hour = (int32_t)dateTime->hour;
|
||||
timeStruct.tm_min = (int32_t)dateTime->minute;
|
||||
timeStruct.tm_sec = (int32_t)dateTime->second;
|
||||
if (asctime_r(&timeStruct, timeStr) != NULL) {
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
(void)len;
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
|
||||
uint32_t TIME_SysTimeGet(BSL_TIME *sysTime)
|
||||
{
|
||||
time_t currentTime;
|
||||
struct timeval tv;
|
||||
uint32_t ret = BSL_SAL_ERR_BAD_PARAM;
|
||||
|
||||
tzset();
|
||||
currentTime = (time_t)BSL_SAL_CurrentSysTimeGet();
|
||||
if (currentTime != 0) {
|
||||
ret = BSL_SAL_UtcTimeToDateConvert(currentTime, sysTime);
|
||||
if (ret == BSL_SUCCESS) {
|
||||
/* milliseconds : non-thread safe */
|
||||
(void)gettimeofday(&tv, NULL);
|
||||
sysTime->millSec = (uint16_t)tv.tv_usec / 1000U; /* 1000 is multiple */
|
||||
sysTime->microSec = (uint32_t)tv.tv_usec % 1000U; /* 1000 is multiple */
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t TIME_UtcTimeToDateConvert(int64_t utcTime, BSL_TIME *sysTime)
|
||||
{
|
||||
struct tm tempTime;
|
||||
time_t utcTimeTmp = (time_t)utcTime;
|
||||
if (gmtime_r(&utcTimeTmp, &tempTime) == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
|
||||
sysTime->year = (uint16_t)((uint16_t)tempTime.tm_year + BSL_TIME_YEAR_START); /* 1900 is base year */
|
||||
sysTime->month = (uint8_t)((uint8_t)tempTime.tm_mon + 1U);
|
||||
sysTime->day = (uint8_t)tempTime.tm_mday;
|
||||
sysTime->hour = (uint8_t)tempTime.tm_hour;
|
||||
sysTime->minute = (uint8_t)tempTime.tm_min;
|
||||
sysTime->second = (uint8_t)tempTime.tm_sec;
|
||||
sysTime->millSec = 0U;
|
||||
sysTime->microSec = 0U;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
void SAL_Sleep(uint32_t time)
|
||||
{
|
||||
sleep(time);
|
||||
}
|
||||
|
||||
long SAL_Tick(void)
|
||||
{
|
||||
struct tms buf = {0};
|
||||
clock_t tickCount = times(&buf);
|
||||
return (long)tickCount;
|
||||
}
|
||||
|
||||
long SAL_TicksPerSec(void)
|
||||
{
|
||||
return sysconf(_SC_CLK_TCK);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "sal_atomic.h"
|
||||
#include "bsl_errno.h"
|
||||
|
||||
int BSL_SAL_AtomicAdd(int *val, int amount, int *ref, BSL_SAL_ThreadLockHandle lock)
|
||||
{
|
||||
if (val == NULL || ref == NULL) {
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
int32_t ret = BSL_SAL_ThreadWriteLock(lock);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
*val += amount;
|
||||
*ref = *val;
|
||||
return BSL_SAL_ThreadUnlock(lock);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_sal.h"
|
||||
|
||||
#ifdef HITLS_BSL_SAL_NET
|
||||
#include "sal_netimpl.h"
|
||||
#endif
|
||||
#ifdef HITLS_BSL_SAL_TIME
|
||||
#include "sal_time_impl.h"
|
||||
#endif
|
||||
#ifdef HITLS_BSL_SAL_FILE
|
||||
#include "sal_fileimpl.h"
|
||||
#endif
|
||||
|
||||
/* The prefix of BSL_SAL_CB_FUNC_TYPE */
|
||||
#ifdef HITLS_BSL_SAL_NET
|
||||
#define BSL_SAL_NET_CB 0x0300
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_BSL_SAL_TIME
|
||||
#define BSL_SAL_TIME_CB 0x0400
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_BSL_SAL_FILE
|
||||
#define BSL_SAL_FILE_CB 0x0500
|
||||
#endif
|
||||
|
||||
int32_t BSL_SAL_CallBack_Ctrl(BSL_SAL_CB_FUNC_TYPE funcType, void *funcCb)
|
||||
{
|
||||
uint32_t type = (uint32_t)funcType & 0xff00;
|
||||
switch (type) {
|
||||
#ifdef HITLS_BSL_SAL_NET
|
||||
case BSL_SAL_NET_CB:
|
||||
return SAL_NetCallback_Ctrl(funcType, funcCb);
|
||||
#endif
|
||||
#ifdef HITLS_BSL_SAL_TIME
|
||||
case BSL_SAL_TIME_CB:
|
||||
return SAL_TimeCallback_Ctrl(funcType, funcCb);
|
||||
#endif
|
||||
#ifdef HITLS_BSL_SAL_FILE
|
||||
case BSL_SAL_FILE_CB:
|
||||
return SAL_FileCallback_Ctrl(funcType, funcCb);
|
||||
#endif
|
||||
default:
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
|
||||
#if defined(HITLS_BSL_SAL_FILE)
|
||||
#include <stdint.h>
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "sal_fileimpl.h"
|
||||
|
||||
static BSL_SAL_FileCallback g_filleCallBack = {0};
|
||||
|
||||
int32_t SAL_FileCallback_Ctrl(BSL_SAL_CB_FUNC_TYPE type, void *funcCb)
|
||||
{
|
||||
if (type > BSL_SAL_FILE_LENGTH_CB_FUNC || type < BSL_SAL_FILE_OPEN_CB_FUNC) {
|
||||
return BSL_SAL_FILE_NO_REG_FUNC;
|
||||
}
|
||||
uint32_t offet = (uint32_t)(type - BSL_SAL_FILE_OPEN_CB_FUNC);
|
||||
((void **)&g_filleCallBack)[offet] = funcCb;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_FileOpen(bsl_sal_file_handle *stream, const char *path, const char *mode)
|
||||
{
|
||||
if (g_filleCallBack.pfFileOpen != NULL && g_filleCallBack.pfFileOpen != BSL_SAL_FileOpen) {
|
||||
return g_filleCallBack.pfFileOpen(stream, path, mode);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_FileOpen(stream, path, mode);
|
||||
#else
|
||||
return BSL_SAL_FILE_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_FileRead(bsl_sal_file_handle stream, void *buffer, size_t size, size_t num, size_t *len)
|
||||
{
|
||||
if (g_filleCallBack.pfFileRead != NULL && g_filleCallBack.pfFileRead != BSL_SAL_FileRead) {
|
||||
return g_filleCallBack.pfFileRead(stream, buffer, size, num, len);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_FileRead(stream, buffer, size, num, len);
|
||||
#else
|
||||
return BSL_SAL_FILE_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_FileWrite(bsl_sal_file_handle stream, const void *buffer, size_t size, size_t num)
|
||||
{
|
||||
if (g_filleCallBack.pfFileWrite != NULL && g_filleCallBack.pfFileWrite != BSL_SAL_FileWrite) {
|
||||
return g_filleCallBack.pfFileWrite(stream, buffer, size, num);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_FileWrite(stream, buffer, size, num);
|
||||
#else
|
||||
return BSL_SAL_FILE_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
void BSL_SAL_FileClose(bsl_sal_file_handle stream)
|
||||
{
|
||||
if (g_filleCallBack.pfFileClose != NULL && g_filleCallBack.pfFileClose != BSL_SAL_FileClose) {
|
||||
g_filleCallBack.pfFileClose(stream);
|
||||
return;
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
SAL_FileClose(stream);
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_FileLength(const char *path, size_t *len)
|
||||
{
|
||||
if (g_filleCallBack.pfFileLength != NULL && g_filleCallBack.pfFileLength != BSL_SAL_FileLength) {
|
||||
return g_filleCallBack.pfFileLength(path, len);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_FileLength(path, len);
|
||||
#else
|
||||
return BSL_SAL_FILE_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_ReadFile(const char *path, uint8_t **buff, uint32_t *len)
|
||||
{
|
||||
size_t readLen;
|
||||
size_t fileLen = 0;
|
||||
int32_t ret = BSL_SAL_FileLength(path, &fileLen);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
bsl_sal_file_handle stream = NULL;
|
||||
ret = BSL_SAL_FileOpen(&stream, path, "rb");
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t *fileBuff = BSL_SAL_Malloc(fileLen + 1);
|
||||
if (fileBuff == NULL) {
|
||||
BSL_SAL_FileClose(stream);
|
||||
return BSL_MALLOC_FAIL;
|
||||
}
|
||||
do {
|
||||
ret = BSL_SAL_FileRead(stream, fileBuff, 1, fileLen, &readLen);
|
||||
BSL_SAL_FileClose(stream);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
fileBuff[fileLen] = '\0';
|
||||
*buff = fileBuff;
|
||||
*len = (uint32_t)fileLen;
|
||||
return ret;
|
||||
} while (0);
|
||||
BSL_SAL_FREE(fileBuff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_WriteFile(const char *path, const uint8_t *buff, uint32_t len)
|
||||
{
|
||||
bsl_sal_file_handle stream = NULL;
|
||||
int32_t ret = BSL_SAL_FileOpen(&stream, path, "wb");
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = BSL_SAL_FileWrite(stream, buff, 1, len);
|
||||
BSL_SAL_FileClose(stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef SAL_FILEIMPL_H
|
||||
#define SAL_FILEIMPL_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_SAL_FILE
|
||||
|
||||
#include <stdint.h>
|
||||
#include "bsl_sal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
typedef struct {
|
||||
BslSalFileOpen pfFileOpen;
|
||||
BslSalFileClose pfFileClose;
|
||||
BslSalFileRead pfFileRead;
|
||||
BslSalFileWrite pfFileWrite;
|
||||
BslSalFileLength pfFileLength;
|
||||
} BSL_SAL_FileCallback;
|
||||
|
||||
int32_t SAL_FileCallback_Ctrl(BSL_SAL_CB_FUNC_TYPE type, void *funcCb);
|
||||
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
int32_t SAL_FileOpen(bsl_sal_file_handle *stream, const char *path, const char *mode);
|
||||
int32_t SAL_FileRead(bsl_sal_file_handle stream, void *buffer, size_t size, size_t num, size_t *len);
|
||||
int32_t SAL_FileWrite(bsl_sal_file_handle stream, const void *buffer, size_t size, size_t num);
|
||||
void SAL_FileClose(bsl_sal_file_handle stream);
|
||||
int32_t SAL_FileLength(const char *path, size_t *len);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // HITLS_BSL_SAL_FILE
|
||||
#endif // SAL_FILEIMPL_H
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef SAL_LOCKIMPL_H
|
||||
#define SAL_LOCKIMPL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hitls_build.h"
|
||||
#include "bsl_sal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifdef HITLS_BSL_SAL_LOCK
|
||||
int32_t SAL_RwLockNew(BSL_SAL_ThreadLockHandle *lock);
|
||||
|
||||
int32_t SAL_RwReadLock(BSL_SAL_ThreadLockHandle rwLock);
|
||||
|
||||
int32_t SAL_RwWriteLock(BSL_SAL_ThreadLockHandle rwLock);
|
||||
|
||||
int32_t SAL_RwUnlock(BSL_SAL_ThreadLockHandle rwLock);
|
||||
|
||||
void SAL_RwLockFree(BSL_SAL_ThreadLockHandle rwLock);
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_BSL_SAL_THREAD
|
||||
int32_t SAL_PthreadRunOnce(uint32_t *onceControl, BSL_SAL_ThreadInitRoutine initFunc);
|
||||
|
||||
uint64_t SAL_GetPid(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // SAL_LOCKIMPL_H
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "securec.h"
|
||||
#include "hitls_build.h"
|
||||
#include "bsl_log_internal.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_binlog_id.h"
|
||||
#include "sal_memimpl.h"
|
||||
|
||||
static BSL_SAL_MemCallback g_memCallback = {0};
|
||||
|
||||
void *BSL_SAL_Malloc(uint32_t size)
|
||||
{
|
||||
// When size is 0, malloc of different systems may return NULL or non-NULL. Here, a definite result is required.
|
||||
// If the callback is registered, everything is determined by the callback.
|
||||
if (g_memCallback.pfMalloc != NULL && g_memCallback.pfMalloc != BSL_SAL_Malloc) {
|
||||
return g_memCallback.pfMalloc(size);
|
||||
}
|
||||
if (size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_MEM
|
||||
return SAL_MallocImpl(size);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void BSL_SAL_Free(void *value)
|
||||
{
|
||||
if (g_memCallback.pfFree == NULL || g_memCallback.pfFree == BSL_SAL_Free) {
|
||||
#ifdef HITLS_BSL_SAL_MEM
|
||||
SAL_FreeImpl(value);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
g_memCallback.pfFree(value);
|
||||
}
|
||||
|
||||
void *BSL_SAL_Calloc(uint32_t num, uint32_t size)
|
||||
{
|
||||
if (num == 0 || size == 0) {
|
||||
return BSL_SAL_Malloc(0);
|
||||
}
|
||||
if (num > UINT32_MAX / size) { // process the rewinding according to G.INT.02 in the HW C Coding Specifications V5.1
|
||||
return NULL;
|
||||
}
|
||||
uint32_t blockSize = num * size;
|
||||
uint8_t *ptr = BSL_SAL_Malloc(blockSize);
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
// If the value is greater than SECUREC_MEM_MAX_LEN, segment processing is required.
|
||||
// This is because memset_s can process only the value which the size is 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) {
|
||||
BSL_SAL_FREE(ptr);
|
||||
return NULL;
|
||||
}
|
||||
offset += SECUREC_MEM_MAX_LEN;
|
||||
blockSize -= SECUREC_MEM_MAX_LEN;
|
||||
}
|
||||
if (memset_s(&ptr[offset], blockSize, 0, blockSize) != EOK) {
|
||||
BSL_SAL_FREE(ptr);
|
||||
return NULL;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *BSL_SAL_Realloc(void *addr, uint32_t newSize, uint32_t oldSize)
|
||||
{
|
||||
if (addr == NULL) {
|
||||
return BSL_SAL_Malloc(newSize);
|
||||
}
|
||||
uint32_t minSize = (oldSize > newSize) ? newSize : oldSize;
|
||||
|
||||
void *ptr = BSL_SAL_Malloc(newSize);
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (memcpy_s(ptr, newSize, addr, minSize) != EOK) {
|
||||
BSL_SAL_FREE(ptr);
|
||||
} else {
|
||||
BSL_SAL_FREE(addr);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *BSL_SAL_Dump(const void *src, uint32_t size)
|
||||
{
|
||||
if (src == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
void *ptr = BSL_SAL_Malloc(size);
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (memcpy_s(ptr, size, src, size) != EOK) {
|
||||
BSL_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)) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05011, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"invalid params", 0, 0, 0, 0);
|
||||
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;
|
||||
/* FALLTHRU */
|
||||
case 15: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
case 14: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
case 13: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
case 12: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
case 11: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
case 10: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
case 9: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
case 8: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
case 7: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
case 6: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
case 5: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
case 4: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
case 3: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
case 2: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
case 1: *(tmp++) = (uint8_t)0;
|
||||
/* FALLTHRU */
|
||||
default:
|
||||
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, used to determine whether 4-byte alignment
|
||||
// shift rightwards by 4 bits and then leftwards by 4 bits, which is used to calculate an integer multiple of 16
|
||||
boundOpt = (bufLen >> 4) << 4;
|
||||
for (uint32_t i = 0; i < boundOpt; i += 16) { // Clear 16 pieces of memory each time.
|
||||
uint32_t *ctmp = (uint32_t *)(tmp + i);
|
||||
ctmp[0] = 0;
|
||||
ctmp[1] = 0;
|
||||
ctmp[2] = 0;
|
||||
ctmp[3] = 0;
|
||||
}
|
||||
} else {
|
||||
// shifted rightward by 2 bits and then left by 2 bits, used to calculate an integer multiple of 4.
|
||||
boundOpt = (bufLen >> 2) << 2;
|
||||
for (uint32_t i = 0; i < boundOpt; i += 4) { // Clear 4 pieces of memory each time.
|
||||
tmp[i] = 0;
|
||||
tmp[i + 1] = 0;
|
||||
tmp[i + 2] = 0;
|
||||
tmp[i + 3] = 0;
|
||||
}
|
||||
}
|
||||
for (uint32_t i = boundOpt; i < bufLen; ++i) {
|
||||
tmp[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void BSL_SAL_CleanseData(void *ptr, uint32_t size)
|
||||
{
|
||||
if (ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
if (size > CLEAN_THRESHOLD_SIZE) {
|
||||
CleanSensitiveData(ptr, size);
|
||||
} else {
|
||||
CleanSensitiveDataLess16Byte(ptr, size);
|
||||
}
|
||||
}
|
||||
|
||||
void BSL_SAL_ClearFree(void *ptr, uint32_t size)
|
||||
{
|
||||
if (ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
if (size != 0) {
|
||||
BSL_SAL_CleanseData(ptr, size);
|
||||
}
|
||||
BSL_SAL_FREE(ptr);
|
||||
}
|
||||
|
||||
#if !defined(__clang__)
|
||||
#pragma GCC pop_options
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef SAL_MEMIMPL_H
|
||||
#define SAL_MEMIMPL_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_SAL_MEM
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void *SAL_MallocImpl(uint32_t size);
|
||||
|
||||
void SAL_FreeImpl(void *value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_BSL_SAL_MEM */
|
||||
|
||||
#endif // SAL_MEMIMPL_H
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
|
||||
#if defined(HITLS_BSL_SAL_NET)
|
||||
#include <stdint.h>
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "sal_netimpl.h"
|
||||
|
||||
static BSL_SAL_NetCallback g_netCallback = {0};
|
||||
|
||||
int32_t SAL_NetCallback_Ctrl(BSL_SAL_CB_FUNC_TYPE type, void *funcCb)
|
||||
{
|
||||
if (type > BSL_SAL_NET_SOCKGETLASTSOCKETERROR_CB_FUNC || type < BSL_SAL_NET_WRITE_CB_FUNC) {
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
}
|
||||
uint32_t offset = (uint32_t)(type - BSL_SAL_NET_WRITE_CB_FUNC);
|
||||
((void **)&g_netCallback)[offset] = funcCb;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_Write(int32_t fd, const void *buf, uint32_t len, int32_t *err)
|
||||
{
|
||||
if (buf == NULL || len == 0 || err == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
if (g_netCallback.pfWrite != NULL && g_netCallback.pfWrite != BSL_SAL_Write) {
|
||||
return g_netCallback.pfWrite(fd, buf, len, err);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_Write(fd, buf, len, err);
|
||||
#else
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_Read(int32_t fd, void *buf, uint32_t len, int32_t *err)
|
||||
{
|
||||
if (buf == NULL || len == 0 || err == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
if (g_netCallback.pfRead != NULL && g_netCallback.pfRead != BSL_SAL_Read) {
|
||||
return g_netCallback.pfRead(fd, buf, len, err);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_Read(fd, buf, len, err);
|
||||
#else
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_Socket(int32_t af, int32_t type, int32_t protocol)
|
||||
{
|
||||
if (g_netCallback.pfSocket != NULL && g_netCallback.pfSocket != BSL_SAL_Socket) {
|
||||
return g_netCallback.pfSocket(af, type, protocol);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_Socket(af, type, protocol);
|
||||
#else
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_SockClose(int32_t sockId)
|
||||
{
|
||||
if (g_netCallback.pfSockClose != NULL && g_netCallback.pfSockClose != BSL_SAL_SockClose) {
|
||||
return g_netCallback.pfSockClose(sockId);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_SockClose(sockId);
|
||||
#else
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_SetSockopt(int32_t sockId, int32_t level, int32_t name, const void *val, uint32_t len)
|
||||
{
|
||||
if (g_netCallback.pfSetSockopt != NULL && g_netCallback.pfSetSockopt != BSL_SAL_SetSockopt) {
|
||||
return g_netCallback.pfSetSockopt(sockId, level, name, val, len);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_SetSockopt(sockId, level, name, val, len);
|
||||
#else
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_GetSockopt(int32_t sockId, int32_t level, int32_t name, void *val, uint32_t *len)
|
||||
{
|
||||
if (g_netCallback.pfGetSockopt != NULL && g_netCallback.pfGetSockopt != BSL_SAL_GetSockopt) {
|
||||
return g_netCallback.pfGetSockopt(sockId, level, name, val, len);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_GetSockopt(sockId, level, name, val, len);
|
||||
#else
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_SockListen(int32_t sockId, int32_t backlog)
|
||||
{
|
||||
if (g_netCallback.pfSockListen != NULL && g_netCallback.pfSockListen != BSL_SAL_SockListen) {
|
||||
return g_netCallback.pfSockListen(sockId, backlog);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_SockListen(sockId, backlog);
|
||||
#else
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_SockBind(int32_t sockId, BSL_SAL_SockAddr addr, size_t len)
|
||||
{
|
||||
if (g_netCallback.pfSockBind != NULL && g_netCallback.pfSockBind != BSL_SAL_SockBind) {
|
||||
return g_netCallback.pfSockBind(sockId, addr, len);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_SockBind(sockId, addr, len);
|
||||
#else
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_SockConnect(int32_t sockId, BSL_SAL_SockAddr addr, size_t len)
|
||||
{
|
||||
if (g_netCallback.pfSockConnect != NULL && g_netCallback.pfSockConnect != BSL_SAL_SockConnect) {
|
||||
return g_netCallback.pfSockConnect(sockId, addr, len);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_SockConnect(sockId, addr, len);
|
||||
#else
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_SockSend(int32_t sockId, const void *msg, size_t len, int32_t flags)
|
||||
{
|
||||
if (g_netCallback.pfSockSend != NULL && g_netCallback.pfSockSend != BSL_SAL_SockSend) {
|
||||
return g_netCallback.pfSockSend(sockId, msg, len, flags);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_SockSend(sockId, msg, len, flags);
|
||||
#else
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_SockRecv(int32_t sockfd, void *buff, size_t len, int32_t flags)
|
||||
{
|
||||
if (g_netCallback.pfSockRecv != NULL && g_netCallback.pfSockRecv != BSL_SAL_SockRecv) {
|
||||
return g_netCallback.pfSockRecv(sockfd, buff, len, flags);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_SockRecv(sockfd, buff, len, flags);
|
||||
#else
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_Select(int32_t nfds, void *readfds, void *writefds, void *exceptfds, void *timeout)
|
||||
{
|
||||
if (g_netCallback.pfSelect != NULL && g_netCallback.pfSelect != BSL_SAL_Select) {
|
||||
return g_netCallback.pfSelect(nfds, readfds, writefds, exceptfds, timeout);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_Select(nfds, readfds, writefds, exceptfds, timeout);
|
||||
#else
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_Ioctlsocket(int32_t sockId, long cmd, unsigned long *arg)
|
||||
{
|
||||
if (g_netCallback.pfIoctlsocket != NULL && g_netCallback.pfIoctlsocket != BSL_SAL_Ioctlsocket) {
|
||||
return g_netCallback.pfIoctlsocket(sockId, cmd, arg);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_Ioctlsocket(sockId, cmd, arg);
|
||||
#else
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_SockGetLastSocketError(void)
|
||||
{
|
||||
if (g_netCallback.pfSockGetLastSocketError != NULL &&
|
||||
g_netCallback.pfSockGetLastSocketError != BSL_SAL_SockGetLastSocketError) {
|
||||
return g_netCallback.pfSockGetLastSocketError();
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_SockGetLastSocketError();
|
||||
#else
|
||||
return BSL_SAL_NET_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef SAL_NETIMPL_H
|
||||
#define SAL_NETIMPL_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_SAL_NET
|
||||
|
||||
#include <stdint.h>
|
||||
#include "bsl_sal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
typedef struct {
|
||||
BslSalWrite pfWrite;
|
||||
BslSalRead pfRead;
|
||||
BslSalSocket pfSocket;
|
||||
BslSalSockClose pfSockClose;
|
||||
BslSalSetSockopt pfSetSockopt;
|
||||
BslSalGetSockopt pfGetSockopt;
|
||||
BslSalSockListen pfSockListen;
|
||||
BslSalSockBind pfSockBind;
|
||||
BslSalSockConnect pfSockConnect;
|
||||
BslSalSockSend pfSockSend;
|
||||
BslSalSockRecv pfSockRecv;
|
||||
BslSalSelect pfSelect;
|
||||
BslSalIoctlsocket pfIoctlsocket;
|
||||
BslSalSockGetLastSocketError pfSockGetLastSocketError;
|
||||
} BSL_SAL_NetCallback;
|
||||
|
||||
int32_t SAL_NetCallback_Ctrl(BSL_SAL_CB_FUNC_TYPE type, void *funcCb);
|
||||
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
int32_t SAL_Write(int32_t fd, const void *buf, uint32_t len, int32_t *err);
|
||||
int32_t SAL_Read(int32_t fd, void *buf, uint32_t len, int32_t *err);
|
||||
int32_t SAL_Socket(int32_t af, int32_t type, int32_t protocol);
|
||||
int32_t SAL_SockClose(int32_t sockId);
|
||||
int32_t SAL_SetSockopt(int32_t sockId, int32_t level, int32_t name, const void *val, uint32_t len);
|
||||
int32_t SAL_GetSockopt(int32_t sockId, int32_t level, int32_t name, void *val, uint32_t *len);
|
||||
int32_t SAL_SockListen(int32_t sockId, int32_t backlog);
|
||||
int32_t SAL_SockBind(int32_t sockId, BSL_SAL_SockAddr addr, size_t len);
|
||||
int32_t SAL_SockConnect(int32_t sockId, BSL_SAL_SockAddr addr, size_t len);
|
||||
int32_t SAL_SockSend(int32_t sockId, const void *msg, size_t len, int32_t flags);
|
||||
int32_t SAL_SockRecv(int32_t sockfd, void *buff, size_t len, int32_t flags);
|
||||
int32_t SAL_Select(int32_t nfds, void *readfds, void *writefds, void *exceptfds, void *timeout);
|
||||
int32_t SAL_Ioctlsocket(int32_t sockId, long cmd, unsigned long *arg);
|
||||
int32_t SAL_SockGetLastSocketError(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // HITLS_BSL_SAL_NET
|
||||
#endif // SAL_NETIMPL_H
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "hitls_build.h"
|
||||
|
||||
#include "bsl_binlog_id.h"
|
||||
#include "bsl_log_internal.h"
|
||||
#include "bsl_log.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "sal_lockimpl.h"
|
||||
#include "bsl_sal.h"
|
||||
|
||||
static BSL_SAL_ThreadCallback g_threadCallback = {0};
|
||||
|
||||
int32_t BSL_SAL_ThreadLockNew(BSL_SAL_ThreadLockHandle *lock)
|
||||
{
|
||||
if ((g_threadCallback.pfThreadLockNew != NULL) && (g_threadCallback.pfThreadLockNew != BSL_SAL_ThreadLockNew)) {
|
||||
return g_threadCallback.pfThreadLockNew(lock);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LOCK
|
||||
return SAL_RwLockNew(lock);
|
||||
#else
|
||||
return BSL_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_ThreadReadLock(BSL_SAL_ThreadLockHandle lock)
|
||||
{
|
||||
if ((g_threadCallback.pfThreadReadLock != NULL) && (g_threadCallback.pfThreadReadLock != BSL_SAL_ThreadReadLock)) {
|
||||
return g_threadCallback.pfThreadReadLock(lock);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LOCK
|
||||
return SAL_RwReadLock(lock);
|
||||
#else
|
||||
return BSL_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_ThreadWriteLock(BSL_SAL_ThreadLockHandle lock)
|
||||
{
|
||||
if ((g_threadCallback.pfThreadWriteLock != NULL) &&
|
||||
(g_threadCallback.pfThreadWriteLock != BSL_SAL_ThreadWriteLock)) {
|
||||
return g_threadCallback.pfThreadWriteLock(lock);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LOCK
|
||||
return SAL_RwWriteLock(lock);
|
||||
#else
|
||||
return BSL_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_ThreadUnlock(BSL_SAL_ThreadLockHandle lock)
|
||||
{
|
||||
if ((g_threadCallback.pfThreadUnlock != NULL) && (g_threadCallback.pfThreadUnlock != BSL_SAL_ThreadUnlock)) {
|
||||
return g_threadCallback.pfThreadUnlock(lock);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LOCK
|
||||
return SAL_RwUnlock(lock);
|
||||
#else
|
||||
return BSL_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
void BSL_SAL_ThreadLockFree(BSL_SAL_ThreadLockHandle lock)
|
||||
{
|
||||
if ((g_threadCallback.pfThreadLockFree != NULL) && (g_threadCallback.pfThreadLockFree != BSL_SAL_ThreadLockFree)) {
|
||||
g_threadCallback.pfThreadLockFree(lock);
|
||||
return;
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LOCK
|
||||
SAL_RwLockFree(lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t BSL_SAL_ThreadGetId(void)
|
||||
{
|
||||
if ((g_threadCallback.pfThreadGetId != NULL) && (g_threadCallback.pfThreadGetId != BSL_SAL_ThreadGetId)) {
|
||||
return g_threadCallback.pfThreadGetId();
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_THREAD
|
||||
return SAL_GetPid();
|
||||
#else
|
||||
return BSL_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_ThreadRunOnce(uint32_t *onceControl, BSL_SAL_ThreadInitRoutine initFunc)
|
||||
{
|
||||
if (onceControl == NULL || initFunc == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_THREAD
|
||||
return SAL_PthreadRunOnce(onceControl, initFunc);
|
||||
#else
|
||||
if (*onceControl == 1) {
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
initFunc();
|
||||
*onceControl = 1;
|
||||
return BSL_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
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)) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05012, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"invalid params", 0, 0, 0, 0);
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,431 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_SAL_TIME
|
||||
|
||||
#include "bsl_sal.h"
|
||||
#include "sal_time_impl.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "sal_time.h"
|
||||
|
||||
static BSL_SAL_TimeCallback g_timeCallback = {0};
|
||||
|
||||
int32_t SAL_TimeCallback_Ctrl(BSL_SAL_CB_FUNC_TYPE type, void *funcCb)
|
||||
{
|
||||
if (type > BSL_SAL_TIME_TICKS_PER_SEC_CB_FUNC || type < BSL_SAL_TIME_GET_SYS_TIME_CB_FUNC) {
|
||||
return BSL_SAL_TIME_NO_REG_FUNC;
|
||||
}
|
||||
uint32_t offset = (uint32_t)(type - BSL_SAL_TIME_GET_SYS_TIME_CB_FUNC);
|
||||
((void **)&g_timeCallback)[offset] = funcCb;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
void BSL_SAL_SysTimeFuncReg(BslTimeFunc func)
|
||||
{
|
||||
if (func != NULL) {
|
||||
g_timeCallback.pfGetSysTime = func;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void BSL_SysTimeFuncUnReg(void)
|
||||
{
|
||||
g_timeCallback.pfGetSysTime = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
bool BSL_IsLeapYear(uint32_t year)
|
||||
{
|
||||
return ((((year % 4U) == 0U) && ((year % 100U) != 0U)) || ((year % 400U) == 0U));
|
||||
}
|
||||
|
||||
static int64_t BslMkTime64Get(const BSL_TIME *inputTime)
|
||||
{
|
||||
int64_t result;
|
||||
uint32_t i;
|
||||
int32_t unixYear;
|
||||
int32_t unixDay;
|
||||
int32_t extraDay = 0;
|
||||
int32_t year = inputTime->year;
|
||||
int32_t month = inputTime->month - 1;
|
||||
int32_t day = inputTime->day;
|
||||
int32_t hour = inputTime->hour;
|
||||
int32_t minute = inputTime->minute;
|
||||
int32_t second = inputTime->second;
|
||||
int32_t monthTable[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
|
||||
|
||||
for (i = BSL_TIME_SYSTEM_EPOCH_YEAR; (int32_t)i < year; i++) {
|
||||
if (BSL_IsLeapYear(i) == true) {
|
||||
extraDay++;
|
||||
}
|
||||
}
|
||||
|
||||
unixYear = year - (int32_t)BSL_TIME_SYSTEM_EPOCH_YEAR;
|
||||
if (BSL_IsLeapYear((uint32_t)year) == true) {
|
||||
for (i = BSL_MONTH_FEB; i < BSL_MONTH_DEC; i++) {
|
||||
monthTable[i] = monthTable[i] + 1;
|
||||
}
|
||||
}
|
||||
|
||||
unixDay = (unixYear * (int32_t)BSL_TIME_DAY_PER_NONLEAP_YEAR) + monthTable[month] + (day - 1) + extraDay;
|
||||
result = unixDay * (int64_t)86400; /* 86400 is the number of seconds in a day */
|
||||
result = (hour * (int64_t)3600) + result; /* 3600 is the number of seconds in a hour */
|
||||
result = (minute * (int64_t)60) + second + result; /* 60 is the number of seconds in a minute */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert the given date structure to the number of seconds since January 1,1970
|
||||
* @param inputTime [IN] Pointer to the date to be converted.
|
||||
* @param utcTime [OUT] Pointer to the storage of the conversion result
|
||||
* @return BSL_SUCCESS successfully executed.
|
||||
* BSL_INTERNAL_EXCEPTION Execution Failure
|
||||
*/
|
||||
static uint32_t BslUtcTimeGet(const BSL_TIME *inputTime, int64_t *utcTime)
|
||||
{
|
||||
int64_t result;
|
||||
|
||||
if (inputTime == NULL || utcTime == NULL) {
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
if (BSL_DateTimeCheck(inputTime) == false) {
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
result = BslMkTime64Get(inputTime);
|
||||
if (result < 0) {
|
||||
*utcTime = -1;
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
} else {
|
||||
*utcTime = result;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
#define BSL_TIMESTR_MINLEN 26
|
||||
|
||||
uint32_t BSL_DateToStrConvert(const BSL_TIME *dateTime, char *timeStr, size_t len)
|
||||
{
|
||||
if (dateTime == NULL || timeStr == NULL || len < BSL_TIMESTR_MINLEN) {
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
if (BSL_DateTimeCheck(dateTime) != true) {
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
if (g_timeCallback.pfDateToStrConvert != NULL && g_timeCallback.pfDateToStrConvert != TIME_DateToStrConvert) {
|
||||
return g_timeCallback.pfDateToStrConvert(dateTime, timeStr, len);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return TIME_DateToStrConvert(dateTime, timeStr, len);
|
||||
#else
|
||||
return BSL_SAL_TIME_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int64_t BSL_SAL_CurrentSysTimeGet(void)
|
||||
{
|
||||
if (g_timeCallback.pfGetSysTime != NULL && g_timeCallback.pfGetSysTime != TIME_GetSysTime) {
|
||||
return g_timeCallback.pfGetSysTime();
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return TIME_GetSysTime();
|
||||
#else
|
||||
BSL_ERR_PUSH_ERROR(BSL_SAL_TIME_NO_REG_FUNC);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t BslDateTimeCmpCheck(const BSL_TIME *dateA, int64_t *utcTimeA,
|
||||
const BSL_TIME *dateB, int64_t *utcTimeB)
|
||||
{
|
||||
if ((dateA == NULL) || (dateB == NULL)) {
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
|
||||
if (BslUtcTimeGet(dateA, utcTimeA) != BSL_SUCCESS) {
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
if (BslUtcTimeGet(dateB, utcTimeB) != BSL_SUCCESS) {
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_DateTimeCompare(const BSL_TIME *dateA, const BSL_TIME *dateB, int64_t *diffSec)
|
||||
{
|
||||
int64_t utcTimeA = 0;
|
||||
int64_t utcTimeB = 0;
|
||||
int64_t dTimeDiff;
|
||||
uint32_t ret;
|
||||
|
||||
if (BslDateTimeCmpCheck(dateA, &utcTimeA, dateB, &utcTimeB) == BSL_SUCCESS) {
|
||||
dTimeDiff = utcTimeA - utcTimeB;
|
||||
if (diffSec != NULL) {
|
||||
*diffSec = dTimeDiff;
|
||||
}
|
||||
|
||||
if (dTimeDiff < 0) {
|
||||
ret = (uint32_t)BSL_TIME_DATE_BEFORE;
|
||||
} else if (dTimeDiff > 0) {
|
||||
ret = (uint32_t)BSL_TIME_DATE_AFTER;
|
||||
} else {
|
||||
ret = (uint32_t)BSL_TIME_CMP_EQUAL;
|
||||
}
|
||||
} else {
|
||||
ret = (uint32_t)BSL_TIME_CMP_ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t TimeCmp(uint32_t a, uint32_t b)
|
||||
{
|
||||
if (a > b) {
|
||||
return BSL_TIME_DATE_AFTER;
|
||||
}
|
||||
if (a < b) {
|
||||
return BSL_TIME_DATE_BEFORE;
|
||||
}
|
||||
return BSL_TIME_CMP_EQUAL;
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_DateTimeCompareByUs(const BSL_TIME *dateA, const BSL_TIME *dateB)
|
||||
{
|
||||
int64_t diffSec = 0;
|
||||
uint32_t ret;
|
||||
|
||||
ret = BSL_SAL_DateTimeCompare(dateA, dateB, &diffSec);
|
||||
if (ret != BSL_TIME_CMP_EQUAL) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = TimeCmp(dateA->millSec, dateB->millSec);
|
||||
if (ret != BSL_TIME_CMP_EQUAL) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return TimeCmp(dateA->microSec, dateB->microSec);
|
||||
}
|
||||
|
||||
uint32_t BSL_DateTimeAddUs(BSL_TIME *dateR, const BSL_TIME *dateA, uint32_t us)
|
||||
{
|
||||
uint32_t ret;
|
||||
int64_t utcTime = 0;
|
||||
|
||||
/* Convert the date into seconds. */
|
||||
ret = BSL_SAL_DateToUtcTimeConvert(dateA, &utcTime);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Convert the increased time to seconds */
|
||||
uint32_t microSec = us + dateA->microSec;
|
||||
uint32_t millSec = (microSec / BSL_SECOND_TRANSFER_RATIO) + dateA->millSec;
|
||||
microSec %= BSL_SECOND_TRANSFER_RATIO;
|
||||
uint32_t second = millSec / BSL_SECOND_TRANSFER_RATIO;
|
||||
millSec %= BSL_SECOND_TRANSFER_RATIO;
|
||||
|
||||
/* Convert to the date after the number of seconds is added */
|
||||
utcTime += (int64_t)second;
|
||||
ret = BSL_SAL_UtcTimeToDateConvert(utcTime, dateR);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Complete milliseconds and microseconds. */
|
||||
dateR->millSec = (uint16_t)millSec;
|
||||
dateR->microSec = microSec;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_DateToUtcTimeConvert(const BSL_TIME *dateTime, int64_t *utcTime)
|
||||
{
|
||||
uint32_t ret = BSL_INTERNAL_EXCEPTION;
|
||||
|
||||
if ((dateTime != NULL) && (utcTime != NULL)) {
|
||||
if (BSL_DateTimeCheck(dateTime) == true) {
|
||||
ret = BslUtcTimeGet(dateTime, utcTime);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool BslFebDayValidCheck(uint16_t year, uint8_t day)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
if ((BSL_IsLeapYear(year) == true) && (day <= BSL_TIME_LEAP_FEBRUARY_DAY)) {
|
||||
ret = true;
|
||||
} else if ((BSL_IsLeapYear(year) == false) && (day <= BSL_TIME_NOLEAP_FEBRUARY_DAY)) {
|
||||
ret = true;
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool BslDayValidCheck(uint16_t year, uint8_t month, uint8_t day)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
switch (month) {
|
||||
case BSL_MONTH_JAN:
|
||||
case BSL_MONTH_MAR:
|
||||
case BSL_MONTH_MAY:
|
||||
case BSL_MONTH_JUL:
|
||||
case BSL_MONTH_AUG:
|
||||
case BSL_MONTH_OCT:
|
||||
case BSL_MONTH_DEC:
|
||||
if (day > BSL_TIME_BIG_MONTH_DAY) {
|
||||
ret = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case BSL_MONTH_APR:
|
||||
case BSL_MONTH_JUN:
|
||||
case BSL_MONTH_SEM:
|
||||
case BSL_MONTH_NOV:
|
||||
if (day > BSL_TIME_SMALL_MONTH_DAY) {
|
||||
ret = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case BSL_MONTH_FEB:
|
||||
ret = BslFebDayValidCheck(year, day);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool BslYearMonthDayCheck(const BSL_TIME *dateTime)
|
||||
{
|
||||
if (dateTime->year < BSL_TIME_SYSTEM_EPOCH_YEAR) {
|
||||
return false;
|
||||
} else if ((dateTime->month < BSL_MONTH_JAN) || (dateTime->month > BSL_MONTH_DEC)) {
|
||||
return false;
|
||||
} else if (dateTime->day < BSL_MONTH_JAN) {
|
||||
return false;
|
||||
} else {
|
||||
return BslDayValidCheck(dateTime->year, dateTime->month, dateTime->day);
|
||||
}
|
||||
}
|
||||
|
||||
static bool BslHourMinSecCheck(const BSL_TIME *dateTime)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
if (dateTime->hour > 23U) {
|
||||
ret = false;
|
||||
} else if (dateTime->minute > 59U) {
|
||||
ret = false;
|
||||
} else if (dateTime->second > 59U) {
|
||||
ret = false;
|
||||
} else if (dateTime->millSec > 999U) {
|
||||
ret = false;
|
||||
} else if (dateTime->microSec > 999U) { /* microseconds does not exceed the maximum value 1000 */
|
||||
ret = false;
|
||||
} else {
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool BSL_DateTimeCheck(const BSL_TIME *dateTime)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
if ((BslYearMonthDayCheck(dateTime) == false) ||
|
||||
(BslHourMinSecCheck(dateTime) == false)) {
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_UtcTimeToDateConvert(int64_t utcTime, BSL_TIME *sysTime)
|
||||
{
|
||||
if (sysTime == NULL || utcTime > BSL_UTCTIME_MAX) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
if (g_timeCallback.pfUtcTimeToDateConvert != NULL &&
|
||||
g_timeCallback.pfUtcTimeToDateConvert != TIME_UtcTimeToDateConvert) {
|
||||
return g_timeCallback.pfUtcTimeToDateConvert(utcTime, sysTime);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return TIME_UtcTimeToDateConvert(utcTime, sysTime);
|
||||
#else
|
||||
return BSL_SAL_TIME_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t BSL_SAL_SysTimeGet(BSL_TIME *sysTime)
|
||||
{
|
||||
if (sysTime == NULL) {
|
||||
return BSL_SAL_ERR_BAD_PARAM;
|
||||
}
|
||||
if (g_timeCallback.pfSysTimeGet != NULL && g_timeCallback.pfSysTimeGet != TIME_SysTimeGet) {
|
||||
return g_timeCallback.pfSysTimeGet(sysTime);
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return TIME_SysTimeGet(sysTime);
|
||||
#else
|
||||
return BSL_SAL_TIME_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
void BSL_SAL_Sleep(uint32_t time)
|
||||
{
|
||||
if (g_timeCallback.pfSleep != NULL && g_timeCallback.pfSleep != BSL_SAL_Sleep) {
|
||||
g_timeCallback.pfSleep(time);
|
||||
return;
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
SAL_Sleep(time);
|
||||
#endif
|
||||
}
|
||||
|
||||
long BSL_SAL_Tick(void)
|
||||
{
|
||||
if (g_timeCallback.pfTick != NULL && g_timeCallback.pfTick != BSL_SAL_Tick) {
|
||||
return g_timeCallback.pfTick();
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_Tick();
|
||||
#else
|
||||
return BSL_SAL_TIME_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
long BSL_SAL_TicksPerSec(void)
|
||||
{
|
||||
if (g_timeCallback.pfTicksPerSec != NULL && g_timeCallback.pfTicksPerSec != BSL_SAL_TicksPerSec) {
|
||||
return g_timeCallback.pfTicksPerSec();
|
||||
}
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
return SAL_TicksPerSec();
|
||||
#else
|
||||
return BSL_SAL_TIME_NO_REG_FUNC;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* HITLS_BSL_SAL_TIME */
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef SAL_TIMEIMPL_H
|
||||
#define SAL_TIMEIMPL_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_SAL_TIME
|
||||
|
||||
#include <stdint.h>
|
||||
#include "bsl_sal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
typedef struct {
|
||||
BslSalGetSysTime pfGetSysTime;
|
||||
BslSalDateToStrConvert pfDateToStrConvert;
|
||||
BslSalSysTimeGet pfSysTimeGet;
|
||||
BslSalUtcTimeToDateConvert pfUtcTimeToDateConvert;
|
||||
BslSalSleep pfSleep;
|
||||
BslSalTick pfTick;
|
||||
BslSalTicksPerSec pfTicksPerSec;
|
||||
} BSL_SAL_TimeCallback;
|
||||
|
||||
int32_t SAL_TimeCallback_Ctrl(BSL_SAL_CB_FUNC_TYPE type, void *funcCb);
|
||||
|
||||
#ifdef HITLS_BSL_SAL_LINUX
|
||||
int64_t TIME_GetSysTime(void);
|
||||
uint32_t TIME_DateToStrConvert(const BSL_TIME *dateTime, char *timeStr, size_t len);
|
||||
uint32_t TIME_SysTimeGet(BSL_TIME *sysTime);
|
||||
uint32_t TIME_UtcTimeToDateConvert(int64_t utcTime, BSL_TIME *sysTime);
|
||||
void SAL_Sleep(uint32_t time);
|
||||
long SAL_Tick(void);
|
||||
long SAL_TicksPerSec(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // HITLS_BSL_SAL_TIME
|
||||
#endif // SAL_TIMEIMPL_H
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef TLV_H
|
||||
#define TLV_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_TLV
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TLV_HEADER_LENGTH (sizeof(uint32_t) + sizeof(uint32_t))
|
||||
|
||||
typedef struct {
|
||||
uint32_t type;
|
||||
uint32_t length;
|
||||
uint8_t *value;
|
||||
} BSL_Tlv;
|
||||
|
||||
/**
|
||||
* @ingroup bsl_tlv
|
||||
* @brief Construct a TLV message based on the TLV structure.
|
||||
*
|
||||
* @param tlv [IN] TLV structure
|
||||
* @param buffer [OUT] Message memory
|
||||
* @param bufLen [IN] Memory length
|
||||
* @param usedLen [OUT] Message length
|
||||
*
|
||||
* @retval BSL_SUCCESS successfully created.
|
||||
* @retval BSL_TLV_ERR_BAD_PARAM Parameter incorrect
|
||||
* @retval BSL_MEMCPY_FAIL Memory Copy Failure
|
||||
*/
|
||||
int32_t BSL_TLV_Pack(const BSL_Tlv *tlv, uint8_t *buffer, uint32_t bufLen, uint32_t *usedLen);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_tlv
|
||||
* @brief Parse the TLV message of the specified type and generate the TLV structure.
|
||||
*
|
||||
* @param wantType [IN] TLV type
|
||||
* @param data [IN] TLV message memory
|
||||
* @param dataLen [IN] Message length
|
||||
* @param tlv [OUT] TLV Structure
|
||||
* @param readLen [OUT] Length of the parsed message
|
||||
*
|
||||
* @retval BSL_SUCCESS parsed successfully.
|
||||
* @retval BSL_TLV_ERR_BAD_PARAM Parameter incorrect
|
||||
* @retval BSL_MEMCPY_FAIL Memory Copy Failure
|
||||
* @retval BSL_TLV_ERR_NO_WANT_TYPE No TLV found
|
||||
*/
|
||||
int32_t BSL_TLV_Parse(uint32_t wantType, const uint8_t *data, uint32_t dataLen, BSL_Tlv *tlv, uint32_t *readLen);
|
||||
|
||||
/**
|
||||
* @ingroup bsl_tlv
|
||||
* @brief Find the TLV of the specified type
|
||||
* and calculate the offset from the memory start address to the TLV data.
|
||||
*
|
||||
* @param wantType [IN] TLV type
|
||||
* @param data [IN] TLV message memory
|
||||
* @param dataLen [IN] Message length
|
||||
* @param offset [OUT] TLV data offset
|
||||
* @param length [OUT] Data length
|
||||
*
|
||||
* @retval BSL_SUCCESS succeeded.
|
||||
* @retval BSL_TLV_ERR_BAD_PARAM Parameter incorrect
|
||||
* @retval BSL_TLV_ERR_NO_WANT_TYPE No TLV found
|
||||
*/
|
||||
int32_t BSL_TLV_FindValuePos(uint32_t wantType, const uint8_t *data, uint32_t dataLen,
|
||||
uint32_t *offset, uint32_t *length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* HITLS_BSL_TLV */
|
||||
#endif // TLV_H
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_TLV
|
||||
|
||||
#include <stdint.h>
|
||||
#include "securec.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_bytes.h"
|
||||
#include "bsl_log_internal.h"
|
||||
#include "bsl_err_internal.h"
|
||||
#include "bsl_binlog_id.h"
|
||||
#include "tlv.h"
|
||||
|
||||
int32_t BSL_TLV_Pack(const BSL_Tlv *tlv, uint8_t *buffer, uint32_t bufLen, uint32_t *usedLen)
|
||||
{
|
||||
uint8_t *curPos = buffer;
|
||||
if ((bufLen < TLV_HEADER_LENGTH) || (tlv->length > bufLen - TLV_HEADER_LENGTH)) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05013, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"TLV build error: bufLen = %u is not enough for tlv length = %u, tlv type = 0x%x.",
|
||||
bufLen, tlv->length, tlv->type, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_TLV_ERR_BAD_PARAM);
|
||||
return BSL_TLV_ERR_BAD_PARAM;
|
||||
}
|
||||
|
||||
/* Write the TLV type */
|
||||
BSL_Uint32ToByte(tlv->type, curPos);
|
||||
curPos += sizeof(uint32_t);
|
||||
/* Write the TLV length */
|
||||
BSL_Uint32ToByte(tlv->length, curPos);
|
||||
curPos += sizeof(uint32_t);
|
||||
/* Write TLV data */
|
||||
if (memcpy_s(curPos, bufLen - TLV_HEADER_LENGTH, tlv->value, tlv->length) != EOK) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05014, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"TLV build error: write tlv value fail, bufLen = %u, tlv length = %u, tlv type = 0x%x.",
|
||||
bufLen, tlv->length, tlv->type, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_MEMCPY_FAIL);
|
||||
return BSL_MEMCPY_FAIL;
|
||||
}
|
||||
|
||||
*usedLen = TLV_HEADER_LENGTH + tlv->length;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t TLV_ParseHeader(const uint8_t *data, uint32_t dataLen, uint32_t *type, uint32_t *length)
|
||||
{
|
||||
const uint8_t *curPos = data;
|
||||
/* Parse the TLV type */
|
||||
uint32_t tlvType = BSL_ByteToUint32(curPos);
|
||||
curPos += sizeof(uint32_t);
|
||||
/* Parse the TLV length */
|
||||
uint32_t tlvLen = BSL_ByteToUint32(curPos);
|
||||
if (tlvLen > dataLen - TLV_HEADER_LENGTH) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05015, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Check TLV header error: dataLen = %u, tlv length = %u, tlv type = 0x%x.", dataLen, tlvLen, tlvType, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_TLV_ERR_BAD_PARAM);
|
||||
return BSL_TLV_ERR_BAD_PARAM;
|
||||
}
|
||||
|
||||
*type = tlvType;
|
||||
*length = tlvLen;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_TLV_Parse(uint32_t wantType, const uint8_t *data, uint32_t dataLen, BSL_Tlv *tlv, uint32_t *readLen)
|
||||
{
|
||||
int32_t ret;
|
||||
const uint8_t *curPos = data;
|
||||
uint32_t remainLen = dataLen;
|
||||
uint32_t type;
|
||||
uint32_t length;
|
||||
while (remainLen >= TLV_HEADER_LENGTH) {
|
||||
/* Parse the TLV type and length */
|
||||
ret = TLV_ParseHeader(curPos, remainLen, &type, &length);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05016, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Parse TLV error: tlv header illegal.", 0, 0, 0, 0);
|
||||
return ret;
|
||||
}
|
||||
remainLen -= (TLV_HEADER_LENGTH + length);
|
||||
|
||||
/* The TLV type matches the expected type */
|
||||
if (wantType == type) {
|
||||
/* Parse the TLV data */
|
||||
if (memcpy_s(tlv->value, tlv->length, curPos + TLV_HEADER_LENGTH, length) != EOK) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05017, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Parse TLV error: write tlv value fail, bufLen = %u, tlv length = %u, tlv type = 0x%x.",
|
||||
tlv->length, length, type, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_MEMCPY_FAIL);
|
||||
return BSL_MEMCPY_FAIL;
|
||||
}
|
||||
tlv->type = type;
|
||||
tlv->length = length;
|
||||
*readLen = dataLen - remainLen;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
/* The TLV type does not match the expected type. Continue to parse the next TLV. */
|
||||
curPos += (TLV_HEADER_LENGTH + length);
|
||||
}
|
||||
/* No matched TLV found */
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05018, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Parse TLV error: no want type(0x%x), dataLen = %u.", wantType, dataLen, 0, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_TLV_ERR_NO_WANT_TYPE);
|
||||
return BSL_TLV_ERR_NO_WANT_TYPE;
|
||||
}
|
||||
|
||||
int32_t BSL_TLV_FindValuePos(uint32_t wantType, const uint8_t *data, uint32_t dataLen,
|
||||
uint32_t *offset, uint32_t *length)
|
||||
{
|
||||
int32_t ret;
|
||||
const uint8_t *curPos = data;
|
||||
uint32_t remainLen = dataLen;
|
||||
uint32_t type;
|
||||
while (remainLen > TLV_HEADER_LENGTH) {
|
||||
/* Parse the TLV type and length */
|
||||
ret = TLV_ParseHeader(curPos, remainLen, &type, length);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05019, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Find TLV error: tlv header illegal.", 0, 0, 0, 0);
|
||||
return ret;
|
||||
}
|
||||
/* The TLV type matches the expected type */
|
||||
if (wantType == type) {
|
||||
*offset = dataLen - remainLen + TLV_HEADER_LENGTH;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
/* The TLV type does not match the expected type. Continue to parse the next TLV. */
|
||||
curPos += (TLV_HEADER_LENGTH + *length);
|
||||
remainLen -= (TLV_HEADER_LENGTH + *length);
|
||||
}
|
||||
/* No matched TLV found */
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05020, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Find TLV error: no want type(0x%x), dataLen = %u.", wantType, dataLen, 0, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_TLV_ERR_NO_WANT_TYPE);
|
||||
return BSL_TLV_ERR_NO_WANT_TYPE;
|
||||
}
|
||||
#endif /* HITLS_BSL_TLV */
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef UIO_BASE_H
|
||||
#define UIO_BASE_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_UIO_PLT
|
||||
|
||||
#include "bsl_uio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct BSL_UIO_MethodStruct {
|
||||
int32_t type;
|
||||
BslUioWriteCb write;
|
||||
BslUioReadCb read;
|
||||
BslUioCtrlCb ctrl;
|
||||
BslUioPutsCb puts;
|
||||
BslUioGetsCb gets;
|
||||
BslUioCreateCb create;
|
||||
BslUioDestroyCb destroy;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup bsl_uio
|
||||
*
|
||||
* @brief Get the fd of the UIO object
|
||||
* @param uio [IN] UIO object
|
||||
* @retval File Descriptor fd
|
||||
*/
|
||||
int32_t BSL_UIO_GetFd(BSL_UIO *uio);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_BSL_UIO_PLT */
|
||||
|
||||
#endif // UIO_BASE_H
|
||||
|
||||
@@ -0,0 +1,559 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_UIO_PLT
|
||||
|
||||
#include "securec.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_binlog_id.h"
|
||||
#include "bsl_log_internal.h"
|
||||
#include "bsl_log.h"
|
||||
#include "bsl_err_internal.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_uio.h"
|
||||
#include "uio_base.h"
|
||||
#include "uio_sctp.h"
|
||||
#include "uio_tcp.h"
|
||||
#include "uio_abstraction.h"
|
||||
|
||||
BSL_UIO_Method *BSL_UIO_NewMethod(void)
|
||||
{
|
||||
BSL_UIO_Method *meth = (BSL_UIO_Method *)BSL_SAL_Calloc(1u, sizeof(BSL_UIO_Method));
|
||||
if (meth == NULL) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05058, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"new method is NULL.", NULL, NULL, NULL, NULL);
|
||||
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return meth;
|
||||
}
|
||||
|
||||
void BSL_UIO_FreeMethod(BSL_UIO_Method *meth)
|
||||
{
|
||||
BSL_SAL_FREE(meth);
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_SetMethodType(BSL_UIO_Method *meth, int32_t type)
|
||||
{
|
||||
if (meth == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05059, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"set method type is NULL.", NULL, NULL, NULL, NULL);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
meth->type = type;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_SetMethod(BSL_UIO_Method *meth, int32_t type, void *func)
|
||||
{
|
||||
if (meth == NULL || func == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05060, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"set method is NULL.", NULL, NULL, NULL, NULL);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case BSL_UIO_WRITE_CB:
|
||||
meth->write = func;
|
||||
break;
|
||||
case BSL_UIO_READ_CB:
|
||||
meth->read = func;
|
||||
break;
|
||||
case BSL_UIO_CTRL_CB:
|
||||
meth->ctrl = func;
|
||||
break;
|
||||
case BSL_UIO_CREATE_CB:
|
||||
meth->create = func;
|
||||
break;
|
||||
case BSL_UIO_DESTROY_CB:
|
||||
meth->destroy = func;
|
||||
break;
|
||||
case BSL_UIO_PUTS_CB:
|
||||
meth->puts = func;
|
||||
break;
|
||||
case BSL_UIO_GETS_CB:
|
||||
meth->gets = func;
|
||||
break;
|
||||
default:
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05025, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"method type is wrong.", NULL, NULL, NULL, NULL);
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
BSL_UIO *BSL_UIO_New(const BSL_UIO_Method *method)
|
||||
{
|
||||
int32_t ret = BSL_SUCCESS;
|
||||
if (method == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05021, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"method is NULL.", 0, 0, 0, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BSL_UIO *uio = (BSL_UIO *)BSL_SAL_Calloc(1, sizeof(struct UIO_ControlBlock));
|
||||
if (uio == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05022, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"uio malloc fail.", 0, 0, 0, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)memcpy_s(&uio->method, sizeof(BSL_UIO_Method), method, sizeof(BSL_UIO_Method));
|
||||
|
||||
BSL_SAL_ReferencesInit(&(uio->references));
|
||||
BSL_UIO_SetIsUnderlyingClosedByUio(uio, false);
|
||||
|
||||
if (uio->method.create != NULL) {
|
||||
ret = uio->method.create(uio);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05023, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"uio create data fail.", 0, 0, 0, 0);
|
||||
BSL_SAL_FREE(uio);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return uio;
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_UpRef(BSL_UIO *uio)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05024, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"uio is NULL.", 0, 0, 0, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
if (uio->references.count == INT32_MAX) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_REF_MAX);
|
||||
return BSL_UIO_REF_MAX;
|
||||
}
|
||||
int val = 0;
|
||||
BSL_SAL_AtomicUpReferences(&(uio->references), &val);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
void BSL_UIO_Free(BSL_UIO *uio)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
return;
|
||||
}
|
||||
int ret = 0;
|
||||
BSL_SAL_AtomicDownReferences(&(uio->references), &ret);
|
||||
if (ret > 0) {
|
||||
return;
|
||||
}
|
||||
if (uio->userData != NULL && uio->userDataFreeFunc != NULL) {
|
||||
(void)uio->userDataFreeFunc(uio->userData);
|
||||
uio->userData = NULL;
|
||||
}
|
||||
if (uio->method.destroy != NULL) {
|
||||
(void)uio->method.destroy(uio);
|
||||
}
|
||||
BSL_SAL_ReferencesFree(&(uio->references));
|
||||
BSL_SAL_FREE(uio);
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_Write(BSL_UIO *uio, const void *data, uint32_t len, uint32_t *writeLen)
|
||||
{
|
||||
if (uio == NULL || uio->method.write == NULL || data == NULL || writeLen == NULL || len == 0) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05026, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"uio write: internal input error.", 0, 0, 0, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
|
||||
return BSL_INTERNAL_EXCEPTION; // if the uio is null, the send size is zero, means no data send;
|
||||
}
|
||||
|
||||
if (uio->init != 1) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_UNINITIALIZED);
|
||||
return BSL_UIO_UNINITIALIZED;
|
||||
}
|
||||
|
||||
int32_t ret = uio->method.write(uio, data, len, writeLen);
|
||||
if (ret == BSL_SUCCESS) {
|
||||
uio->writeNum += (int64_t)*writeLen;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_Puts(BSL_UIO *uio, const char *buf, uint32_t *writeLen)
|
||||
{
|
||||
if (uio == NULL || uio->method.puts == NULL || writeLen == NULL || buf == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
|
||||
if (uio->init != 1) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_UNINITIALIZED);
|
||||
return BSL_UIO_UNINITIALIZED;
|
||||
}
|
||||
|
||||
int32_t ret = uio->method.puts(uio, buf, writeLen);
|
||||
if (ret == BSL_SUCCESS) {
|
||||
uio->writeNum += (int64_t)*writeLen;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_Gets(BSL_UIO *uio, char *buf, uint32_t *readLen)
|
||||
{
|
||||
if (uio == NULL || uio->method.gets == NULL || readLen == NULL || buf == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
|
||||
if (uio->init != 1) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_UNINITIALIZED);
|
||||
return BSL_UIO_UNINITIALIZED;
|
||||
}
|
||||
|
||||
int32_t ret = uio->method.gets(uio, buf, readLen);
|
||||
if (ret == BSL_SUCCESS) {
|
||||
uio->readNum += (int64_t)*readLen;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_Read(BSL_UIO *uio, void *data, uint32_t len, uint32_t *readLen)
|
||||
{
|
||||
if (uio == NULL || uio->method.read == NULL || data == NULL || len == 0 || readLen == NULL) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05027, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"uio read: internal input error.", 0, 0, 0, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
|
||||
return BSL_INTERNAL_EXCEPTION;
|
||||
}
|
||||
|
||||
if (uio->init != 1) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_UNINITIALIZED);
|
||||
return BSL_UIO_UNINITIALIZED;
|
||||
}
|
||||
|
||||
int32_t ret = uio->method.read(uio, data, len, readLen);
|
||||
if (ret == BSL_SUCCESS) {
|
||||
uio->readNum += (int64_t)*readLen;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_GetTransportType(const BSL_UIO *uio)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05028, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"uio is NULL.", 0, 0, 0, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
return uio->method.type;
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_SetUserData(BSL_UIO *uio, void *data)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05029, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "uio is NULL.", 0, 0, 0, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
|
||||
uio->userData = data;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_SetUserDataFreeFunc(BSL_UIO *uio, BSL_UIO_USERDATA_FREE_FUNC userDataFreeFunc)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
uio->userDataFreeFunc = userDataFreeFunc;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
void *BSL_UIO_GetUserData(const BSL_UIO *uio)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return uio->userData;
|
||||
}
|
||||
|
||||
bool BSL_UIO_GetIsUnderlyingClosedByUio(const BSL_UIO *uio)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
return false; // If the value is empty, the function will not release the value.
|
||||
}
|
||||
return uio->isUnderlyingClosedByUio;
|
||||
}
|
||||
|
||||
void BSL_UIO_SetIsUnderlyingClosedByUio(BSL_UIO *uio, bool close)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
return;
|
||||
}
|
||||
uio->isUnderlyingClosedByUio = close;
|
||||
}
|
||||
|
||||
const BSL_UIO_Method *BSL_UIO_GetMethod(const BSL_UIO *uio)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return &uio->method;
|
||||
}
|
||||
|
||||
static int32_t UIO_GetInit(BSL_UIO *uio, int32_t larg, bool *parg)
|
||||
{
|
||||
if (larg != (int32_t)sizeof(bool) || parg == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
*parg = uio->init;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t UIO_GetReadNum(BSL_UIO *uio, int32_t larg, int64_t *parg)
|
||||
{
|
||||
if (larg != (int32_t)sizeof(int64_t) || parg == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
*parg = uio->readNum;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t UIO_GetWriteNum(BSL_UIO *uio, int32_t larg, int64_t *parg)
|
||||
{
|
||||
if (larg != (int32_t)sizeof(int64_t) || parg == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
*parg = uio->writeNum;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_Ctrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg)
|
||||
{
|
||||
if (uio == NULL || uio->method.ctrl == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
switch (cmd) {
|
||||
case BSL_UIO_GET_INIT:
|
||||
return UIO_GetInit(uio, larg, parg);
|
||||
case BSL_UIO_GET_READ_NUM:
|
||||
return UIO_GetReadNum(uio, larg, parg);
|
||||
case BSL_UIO_GET_WRITE_NUM:
|
||||
return UIO_GetWriteNum(uio, larg, parg);
|
||||
default:
|
||||
return uio->method.ctrl(uio, cmd, larg, parg);
|
||||
}
|
||||
}
|
||||
|
||||
void *BSL_UIO_GetCtx(const BSL_UIO *uio)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return uio->ctx;
|
||||
}
|
||||
|
||||
void BSL_UIO_SetCtx(BSL_UIO *uio, void *ctx)
|
||||
{
|
||||
if (uio != NULL) {
|
||||
uio->ctx = ctx;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_GetFd(BSL_UIO *uio)
|
||||
{
|
||||
int32_t fd = -1;
|
||||
(void)BSL_UIO_Ctrl(uio, BSL_UIO_GET_FD, (int32_t)sizeof(fd), &fd); // Parameters are checked by each ctrl function.
|
||||
return fd;
|
||||
}
|
||||
|
||||
void BSL_UIO_SetFd(BSL_UIO *uio, int fd)
|
||||
{
|
||||
bool invalid = (uio == NULL) || (fd < 0);
|
||||
if (invalid) {
|
||||
return;
|
||||
}
|
||||
BSL_UIO_Ctrl(uio, BSL_UIO_SET_FD, (int32_t)sizeof(fd), &fd);
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_SetFlags(BSL_UIO *uio, uint32_t flags)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
uint32_t validFlags =
|
||||
BSL_UIO_FLAGS_RWS | BSL_UIO_FLAGS_SHOULD_RETRY | BSL_UIO_FLAGS_BASE64_NO_NEWLINE | BSL_UIO_FLAGS_BASE64_PEM;
|
||||
if ((flags & validFlags) == 0 || flags > validFlags) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
|
||||
uio->flags |= flags;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_ClearFlags(BSL_UIO *uio, uint32_t flags)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
uio->flags &= ~flags;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t BSL_UIO_TestFlags(const BSL_UIO *uio, uint32_t flags, uint32_t *out)
|
||||
{
|
||||
if (uio == NULL || out == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
*out = uio->flags & flags;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
void BSL_UIO_SetInit(BSL_UIO *uio, bool init)
|
||||
{
|
||||
if (uio != NULL) {
|
||||
uio->init = init;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checking for Fatal I/O Errors
|
||||
*
|
||||
* @param err [IN] error type
|
||||
*
|
||||
* @return true :Fatal error
|
||||
* false:No fatal errors
|
||||
*/
|
||||
bool UioIsNonFatalErr(int32_t err)
|
||||
{
|
||||
bool ret = true;
|
||||
/** @alias Check whether err is a fatal error and modify ret. */
|
||||
switch (err) {
|
||||
#if defined(ENOTCONN)
|
||||
case ENOTCONN:
|
||||
#endif
|
||||
|
||||
#ifdef EINTR
|
||||
case EINTR:
|
||||
#endif
|
||||
|
||||
#ifdef EINPROGRESS
|
||||
case EINPROGRESS:
|
||||
#endif
|
||||
|
||||
#ifdef EWOULDBLOCK
|
||||
#if !defined(WSAEWOULDBLOCK) || WSAEWOULDBLOCK != EWOULDBLOCK
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef EAGAIN
|
||||
#if EWOULDBLOCK != EAGAIN
|
||||
case EAGAIN:
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef EALREADY
|
||||
case EALREADY:
|
||||
#endif
|
||||
|
||||
#ifdef EPROTO
|
||||
case EPROTO:
|
||||
#endif
|
||||
ret = true;
|
||||
break;
|
||||
default:
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t BSL_UIO_Append(BSL_UIO *uio, BSL_UIO *tail)
|
||||
{
|
||||
bool invalid = (uio == NULL) || (tail == NULL);
|
||||
if (invalid) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
BSL_UIO *t = uio;
|
||||
while (t->next != NULL) {
|
||||
t = t->next;
|
||||
}
|
||||
t->next = tail;
|
||||
tail->prev = t;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
BSL_UIO *BSL_UIO_PopCurrent(BSL_UIO *uio)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
BSL_UIO *ret = uio->next;
|
||||
if (uio->prev != NULL) {
|
||||
uio->prev->next = uio->next;
|
||||
}
|
||||
if (uio->next != NULL) {
|
||||
uio->next->prev = uio->prev;
|
||||
}
|
||||
uio->prev = NULL;
|
||||
uio->next = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void BSL_UIO_FreeChain(BSL_UIO *uio)
|
||||
{
|
||||
BSL_UIO *b = uio;
|
||||
while (b != NULL) {
|
||||
int ref = b->references.count;
|
||||
BSL_UIO *next = b->next;
|
||||
BSL_UIO_Free(b);
|
||||
if (ref > 1) {
|
||||
break;
|
||||
}
|
||||
b = next;
|
||||
}
|
||||
}
|
||||
|
||||
BSL_UIO *BSL_UIO_Next(BSL_UIO *uio)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return uio->next;
|
||||
}
|
||||
|
||||
#endif /* HITLS_BSL_UIO_PLT */
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef UIO_ABSTRACTION_H
|
||||
#define UIO_ABSTRACTION_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_UIO_PLT
|
||||
|
||||
#include "bsl_uio.h"
|
||||
#include "uio_base.h"
|
||||
#include "sal_atomic.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define IP_ADDR_V4_LEN 4
|
||||
#define IP_ADDR_V6_LEN 16
|
||||
#define IP_ADDR_MAX_LEN IP_ADDR_V6_LEN
|
||||
|
||||
|
||||
struct UIO_ControlBlock {
|
||||
struct BSL_UIO_MethodStruct method;
|
||||
|
||||
uint32_t flags; // Read/write retry flag. For details, see BSL_UIO_FLAGS_* in bsl_uio.h
|
||||
bool init; // Initialization flag. 1 means it's initialized, and 0 means it's not initialized.
|
||||
|
||||
int64_t writeNum; // count of write
|
||||
int64_t readNum; // count of read
|
||||
|
||||
void *ctx; // Context
|
||||
uint32_t ctxLen; // Context length
|
||||
|
||||
void *userData; // User data
|
||||
BSL_UIO_USERDATA_FREE_FUNC userDataFreeFunc; // Release User Data
|
||||
|
||||
struct UIO_ControlBlock *prev; // Previous UIO object of the current UIO object in the UIO chain
|
||||
struct UIO_ControlBlock *next; // Next UIO object of the current UIO object in the UIO chain
|
||||
|
||||
bool isUnderlyingClosedByUio; // Indicates whether related resources are released together with the UIO.
|
||||
BSL_SAL_RefCount references; // reference count
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Check whether a given error code is a fatal error.
|
||||
*
|
||||
* @param err [IN] Error code.
|
||||
*
|
||||
* @return true: A fatal error occurs.
|
||||
* false: No fatal error occurs.
|
||||
*/
|
||||
bool UioIsNonFatalErr(int32_t err);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_BSL_UIO_PLT */
|
||||
|
||||
#endif // UIO_ABSTRACTION_H
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_UIO_BUFFER
|
||||
|
||||
#include "securec.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_err_internal.h"
|
||||
#include "bsl_uio.h"
|
||||
#include "uio_abstraction.h"
|
||||
|
||||
// The write behavior must be the same.
|
||||
#define UIO_BUFFER_DEFAULT_SIZE 4096
|
||||
|
||||
typedef struct {
|
||||
uint32_t outSize;
|
||||
// This variable will make the write() logic consistent with the ossl. Reason:
|
||||
// 1) The handshake logic is complex.
|
||||
// 2) The behavior consistency problem of the handshake logic is difficult to locate.
|
||||
uint32_t outOff;
|
||||
uint32_t outLen;
|
||||
uint8_t *outBuf;
|
||||
} BufferCtx;
|
||||
|
||||
static int32_t BufferCreate(BSL_UIO *uio)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
BufferCtx *ctx = BSL_SAL_Calloc(1, sizeof(BufferCtx));
|
||||
if (ctx == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
|
||||
return BSL_MALLOC_FAIL;
|
||||
}
|
||||
ctx->outSize = UIO_BUFFER_DEFAULT_SIZE;
|
||||
ctx->outBuf = (uint8_t *)BSL_SAL_Malloc(UIO_BUFFER_DEFAULT_SIZE);
|
||||
if (ctx->outBuf == NULL) {
|
||||
BSL_SAL_FREE(ctx);
|
||||
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
|
||||
return BSL_MALLOC_FAIL;
|
||||
}
|
||||
BSL_UIO_SetCtx(uio, ctx);
|
||||
uio->init = 1;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BufferDestroy(BSL_UIO *uio)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
BufferCtx *ctx = BSL_UIO_GetCtx(uio);
|
||||
if (ctx != NULL) {
|
||||
BSL_SAL_FREE(ctx->outBuf);
|
||||
BSL_SAL_FREE(ctx);
|
||||
BSL_UIO_SetCtx(uio, NULL);
|
||||
}
|
||||
uio->flags = 0;
|
||||
uio->init = 0;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BufferFlushInternal(BSL_UIO *uio)
|
||||
{
|
||||
BufferCtx *ctx = BSL_UIO_GetCtx(uio);
|
||||
if (ctx == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
while (ctx->outLen > 0) {
|
||||
uint32_t tmpWriteLen = 0;
|
||||
int32_t ret = BSL_UIO_Write(uio->next, &ctx->outBuf[ctx->outOff], ctx->outLen, &tmpWriteLen);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
uio->flags = uio->next->flags;
|
||||
return ret;
|
||||
}
|
||||
if (tmpWriteLen == 0) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_BUSY);
|
||||
return BSL_UIO_IO_BUSY;
|
||||
}
|
||||
ctx->outOff += tmpWriteLen;
|
||||
ctx->outLen -= tmpWriteLen;
|
||||
}
|
||||
ctx->outOff = 0;
|
||||
ctx->outLen = 0;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BufferFlush(BSL_UIO *uio, int32_t larg, void *parg)
|
||||
{
|
||||
bool invalid = (uio == NULL) || (uio->next == NULL) || (uio->ctx == NULL);
|
||||
if (invalid) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
BufferCtx *ctx = BSL_UIO_GetCtx(uio);
|
||||
if (ctx->outLen == 0) { // invoke the flush of the next UIO object
|
||||
return BSL_UIO_Ctrl(uio->next, BSL_UIO_FLUSH, larg, parg);
|
||||
}
|
||||
(void)BSL_UIO_ClearFlags(uio, (BSL_UIO_FLAGS_RWS | BSL_UIO_FLAGS_SHOULD_RETRY));
|
||||
int32_t ret = BufferFlushInternal(uio);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(ret);
|
||||
return ret;
|
||||
}
|
||||
return BSL_UIO_Ctrl(uio->next, BSL_UIO_FLUSH, larg, parg);
|
||||
}
|
||||
|
||||
static int32_t BufferReset(BSL_UIO *uio)
|
||||
{
|
||||
if (uio == NULL || uio->ctx == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
BufferCtx *ctx = uio->ctx;
|
||||
ctx->outLen = 0;
|
||||
ctx->outOff = 0;
|
||||
|
||||
if (uio->next == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
return BSL_UIO_Ctrl(uio->next, BSL_UIO_RESET, 0, NULL);
|
||||
}
|
||||
|
||||
static int32_t BufferCtrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case BSL_UIO_FLUSH:
|
||||
return BufferFlush(uio, larg, parg);
|
||||
case BSL_UIO_RESET:
|
||||
return BufferReset(uio);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
|
||||
return BSL_UIO_FAIL;
|
||||
}
|
||||
|
||||
// Add data to the remaining space.
|
||||
static int32_t TryCompleteBuffer(BufferCtx *ctx, const void *in, uint32_t remain, uint32_t *writeLen)
|
||||
{
|
||||
const uint32_t freeSpace = ctx->outSize - (ctx->outOff + ctx->outLen);
|
||||
if (freeSpace == 0) {
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
const uint32_t real = (freeSpace < remain) ? freeSpace : remain;
|
||||
if (memcpy_s(&ctx->outBuf[ctx->outOff + ctx->outLen], freeSpace, in, real) != EOK) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
ctx->outLen += real;
|
||||
*writeLen += real;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BufferWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen)
|
||||
{
|
||||
bool invalid = (uio == NULL) || (buf == NULL) || (writeLen == NULL) || (uio->next == NULL);
|
||||
if (invalid) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
*writeLen = 0;
|
||||
BufferCtx *ctx = BSL_UIO_GetCtx(uio);
|
||||
invalid = (ctx == NULL) || (ctx->outBuf == NULL);
|
||||
if (invalid) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
(void)BSL_UIO_ClearFlags(uio, (BSL_UIO_FLAGS_RWS | BSL_UIO_FLAGS_SHOULD_RETRY));
|
||||
const uint8_t *in = buf;
|
||||
uint32_t remain = len;
|
||||
while (remain > 0) {
|
||||
const uint32_t freeSpace = ctx->outSize - (ctx->outOff + ctx->outLen);
|
||||
if (freeSpace >= remain) { // If the space is sufficient, cache the data.
|
||||
return TryCompleteBuffer(ctx, in, remain, writeLen);
|
||||
}
|
||||
// else: space is insufficient
|
||||
if (ctx->outLen > 0) { // buffer already has data, need to send the existing data first.
|
||||
int32_t ret = BufferFlushInternal(uio);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ctx->outOff = 0;
|
||||
while (remain >= ctx->outSize) {
|
||||
uint32_t tmpWriteLen = 0;
|
||||
int32_t ret = BSL_UIO_Write(uio->next, in, remain, &tmpWriteLen);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
uio->flags = uio->next->flags;
|
||||
return ret;
|
||||
}
|
||||
*writeLen += tmpWriteLen;
|
||||
in = &in[tmpWriteLen];
|
||||
remain -= tmpWriteLen;
|
||||
}
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
const BSL_UIO_Method *BSL_UIO_BufferMethod(void)
|
||||
{
|
||||
static const BSL_UIO_Method m = {
|
||||
BSL_UIO_BUFFER,
|
||||
BufferWrite,
|
||||
NULL,
|
||||
BufferCtrl,
|
||||
NULL,
|
||||
NULL,
|
||||
BufferCreate,
|
||||
BufferDestroy,
|
||||
};
|
||||
return &m;
|
||||
}
|
||||
#endif /* HITLS_BSL_UIO_BUFFER */
|
||||
@@ -0,0 +1,540 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_UIO_SCTP
|
||||
|
||||
#include <unistd.h>
|
||||
#include "securec.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_binlog_id.h"
|
||||
#include "bsl_log_internal.h"
|
||||
#include "bsl_log.h"
|
||||
#include "bsl_err_internal.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_uio.h"
|
||||
#include "sal_net.h"
|
||||
#include "uio_base.h"
|
||||
#include "uio_abstraction.h"
|
||||
|
||||
#define SCTP_DATA_CHUNK_TYPE 0x00
|
||||
#define SCTP_FORWARD_TSN_CHUNK_TYPE 0xc0
|
||||
#define SCTP_GAUTH_CHUNKS_SIZE 256u
|
||||
#define SCTP_SHARED_AUTHKEY_LEN 64u
|
||||
#define SCTP_SHARE_AUTHKEY_ID_MAX 65535
|
||||
|
||||
typedef struct {
|
||||
bool peerAuthed; /* Whether auth is enabled at the peer end */
|
||||
/* Whether authkey is added: If authkey is added but not active, success is returned when authkey is added again. */
|
||||
bool isAddAuthkey;
|
||||
bool reverse[2]; /* Four-byte alignment is reserved. */
|
||||
|
||||
uint16_t sendAppStreamId; /* ID of the stream sent by the user-specified app. */
|
||||
uint16_t prevShareKeyId;
|
||||
uint16_t shareKeyId;
|
||||
uint16_t reverse1; /* Four-byte alignment is reserved. */
|
||||
|
||||
int32_t fd; // Network socket
|
||||
uint8_t ip[IP_ADDR_MAX_LEN];
|
||||
uint32_t ipLen;
|
||||
bool isAppMsg; // whether the message sent is the app message
|
||||
} SctpParameters;
|
||||
|
||||
static int32_t SctpNew(BSL_UIO *uio)
|
||||
{
|
||||
SctpParameters *parameters = (SctpParameters *)BSL_SAL_Calloc(1u, sizeof(SctpParameters));
|
||||
if (parameters == NULL) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05031, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio: sctp param malloc fail.", 0, 0, 0, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
|
||||
return BSL_UIO_FAIL;
|
||||
}
|
||||
parameters->fd = -1;
|
||||
uio->ctx = parameters;
|
||||
uio->ctxLen = sizeof(SctpParameters);
|
||||
// Specifies whether to be closed by uio when setting fd.
|
||||
// The default value of init is 0. Set the value of init to 1 after the fd is set.
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t SctpDestroy(BSL_UIO *uio)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
SctpParameters *ctx = BSL_UIO_GetCtx(uio);
|
||||
uio->init = 0;
|
||||
if (ctx != NULL) {
|
||||
if (BSL_UIO_GetIsUnderlyingClosedByUio(uio) && ctx->fd != -1) {
|
||||
(void)BSL_SAL_SockClose(ctx->fd);
|
||||
}
|
||||
BSL_SAL_FREE(ctx);
|
||||
BSL_UIO_SetCtx(uio, NULL);
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BslSctpGetSendStreamId(const BSL_UIO *uio, void *parg, int32_t larg)
|
||||
{
|
||||
SctpParameters *parameters = uio->ctx;
|
||||
if (larg != (int32_t)sizeof(uint16_t) || parg == NULL) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05046, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio: Sctp input err.", 0, 0, 0, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
uint16_t *sendStreamId = (uint16_t *)parg;
|
||||
if (parameters->isAppMsg) {
|
||||
*sendStreamId = parameters->sendAppStreamId;
|
||||
} else {
|
||||
*sendStreamId = 0;
|
||||
}
|
||||
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05047, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio: User Get SCTP send StreamId [%hu].", *sendStreamId, 0, 0, 0);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BslSctpSetAppStreamId(SctpParameters *parameters, const void *parg, int32_t larg)
|
||||
{
|
||||
if (larg != (int32_t)sizeof(uint16_t) || parg == NULL) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05048, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio: Sctp input err.", 0, 0, 0, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
parameters->sendAppStreamId = *(const uint16_t *)parg;
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05055, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio: User set SCTP AppStreamId [%hu].", parameters->sendAppStreamId, 0, 0, 0);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BslSctpSetPeerIpAddr(SctpParameters *parameters, const uint8_t *addr, uint32_t size)
|
||||
{
|
||||
if (addr == NULL) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05049, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio: NULL error.", 0, 0, 0, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
|
||||
if (size != IP_ADDR_V4_LEN && size != IP_ADDR_V6_LEN) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05050, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio: Set peer ip address input error.", 0, 0, 0, 0);
|
||||
return BSL_UIO_FAIL;
|
||||
}
|
||||
|
||||
(void)memcpy_s(parameters->ip, sizeof(parameters->ip), addr, size);
|
||||
parameters->ipLen = size;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BslSctpGetPeerIpAddr(SctpParameters *parameters, void *parg, int32_t larg)
|
||||
{
|
||||
BSL_UIO_CtrlGetPeerIpAddrParam *para = (BSL_UIO_CtrlGetPeerIpAddrParam *)parg;
|
||||
if (parg == NULL || larg != (int32_t)sizeof(BSL_UIO_CtrlGetPeerIpAddrParam) ||
|
||||
para->addr == NULL) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05051, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio: Get peer ip address input error.", 0, 0, 0, 0);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
|
||||
/* Check whether the IP address is set. */
|
||||
if (parameters->ipLen == 0) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05052, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio: Ip address is already existed.", 0, 0, 0, 0);
|
||||
return BSL_UIO_FAIL;
|
||||
}
|
||||
|
||||
if (para->size < parameters->ipLen) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05053, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio: Ip address length err.", 0, 0, 0, 0);
|
||||
return BSL_UIO_FAIL;
|
||||
}
|
||||
|
||||
(void)memcpy_s(para->addr, para->size, parameters->ip, parameters->ipLen);
|
||||
para->size = parameters->ipLen;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BslSctpSetFd(BSL_UIO *uio, int32_t size, const int32_t *fd)
|
||||
{
|
||||
if (fd == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
if (size != (int32_t)sizeof(*fd)) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
SctpParameters *sctpCtx = BSL_UIO_GetCtx(uio);
|
||||
if (sctpCtx == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
if (sctpCtx->fd != -1) {
|
||||
if (BSL_UIO_GetIsUnderlyingClosedByUio(uio)) {
|
||||
(void)BSL_SAL_SockClose(sctpCtx->fd);
|
||||
}
|
||||
}
|
||||
sctpCtx->fd = *fd;
|
||||
uio->init = 1;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BslSctpGetFd(SctpParameters *parameters, void *parg, int32_t larg)
|
||||
{
|
||||
if (larg != (int32_t)sizeof(int32_t) || parg == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05054, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"get fd handle invalid parameter.", 0, 0, 0, 0);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
*(int32_t *)parg = parameters->fd;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BslSctpMaskAppMsg(SctpParameters *parameters, void *parg, int32_t larg)
|
||||
{
|
||||
if (parg == NULL || larg != sizeof(bool)) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05030, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"mask app msg failed", 0, 0, 0, 0);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
parameters->isAppMsg = *(bool *)parg;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static bool BslSctpCheckPeerAuth(BSL_UIO *uio, void *parg, int32_t larg)
|
||||
{
|
||||
if (parg == NULL || larg != sizeof(bool)) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05061, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"check peer auth failed", 0, 0, 0, 0);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
int32_t fd = BSL_UIO_GetFd(uio);
|
||||
if (fd < 0) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
|
||||
uint32_t optLen = sizeof(struct sctp_authchunks) + SCTP_GAUTH_CHUNKS_SIZE;
|
||||
struct sctp_authchunks *auth = (struct sctp_authchunks*)BSL_SAL_Calloc(1u, optLen);
|
||||
if (auth == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
|
||||
return BSL_MALLOC_FAIL;
|
||||
}
|
||||
int32_t ret = BSL_SAL_GetSockopt(fd, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, auth, &optLen);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_SAL_Free(auth);
|
||||
BSL_ERR_PUSH_ERROR(BSL_SAL_ERR_NET_GETSOCKOPT);
|
||||
return BSL_SAL_ERR_NET_GETSOCKOPT;
|
||||
}
|
||||
bool dataChunkFlag = false;
|
||||
bool forwardTsnChunkFlag = false;
|
||||
for (uint32_t i = 0; i < auth->gauth_number_of_chunks; i++) {
|
||||
if (auth->gauth_chunks[i] == SCTP_DATA_CHUNK_TYPE) {
|
||||
dataChunkFlag = true;
|
||||
} else if (auth->gauth_chunks[i] == SCTP_FORWARD_TSN_CHUNK_TYPE) {
|
||||
forwardTsnChunkFlag = true;
|
||||
}
|
||||
}
|
||||
if (dataChunkFlag && forwardTsnChunkFlag) {
|
||||
*(bool *)parg = true;
|
||||
}
|
||||
BSL_SAL_Free(auth);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t AddAuthKey(BSL_UIO *uio, SctpParameters *parameters, struct sctp_authkey *auth, socklen_t optLen,
|
||||
uint16_t prevShareKeyId)
|
||||
{
|
||||
int32_t fd = BSL_UIO_GetFd(uio);
|
||||
if (fd < 0) {
|
||||
parameters->shareKeyId = prevShareKeyId;
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
int32_t ret = BSL_SAL_SetSockopt(fd, IPPROTO_SCTP, SCTP_AUTH_KEY, auth, optLen);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
parameters->shareKeyId = prevShareKeyId;
|
||||
BSL_ERR_PUSH_ERROR(BSL_SAL_ERR_NET_SETSOCKOPT);
|
||||
return BSL_SAL_ERR_NET_SETSOCKOPT;
|
||||
}
|
||||
parameters->isAddAuthkey = true;
|
||||
parameters->prevShareKeyId = prevShareKeyId;
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05035, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio: SCTP Set auth key(id:%u) success.", parameters->shareKeyId, 0, 0, 0);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BslSctpAddAuthKey(BSL_UIO *uio, void *parg, int32_t larg)
|
||||
{
|
||||
if (parg == NULL || larg != sizeof(BSL_UIO_SctpAuthKey)) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05062, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"add auth key failed", 0, 0, 0, 0);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
BSL_UIO_SctpAuthKey *key = (BSL_UIO_SctpAuthKey *)parg;
|
||||
SctpParameters *parameters = (SctpParameters *)BSL_UIO_GetCtx(uio);
|
||||
|
||||
if (parameters->isAddAuthkey) {
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
uint16_t prevShareKeyId = parameters->shareKeyId;
|
||||
if (parameters->shareKeyId >= SCTP_SHARE_AUTHKEY_ID_MAX) {
|
||||
parameters->shareKeyId = 1;
|
||||
} else {
|
||||
parameters->shareKeyId++;
|
||||
}
|
||||
key->shareKeyId = parameters->shareKeyId;
|
||||
const uint8_t *authKey = key->authKey;
|
||||
uint16_t size = key->authKeySize;
|
||||
if (size != SCTP_SHARED_AUTHKEY_LEN) {
|
||||
parameters->shareKeyId = prevShareKeyId;
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
socklen_t optLen = sizeof(struct sctp_authkey) + SCTP_SHARED_AUTHKEY_LEN * sizeof(uint8_t);
|
||||
struct sctp_authkey *auth = (struct sctp_authkey *)BSL_SAL_Calloc(1u, optLen);
|
||||
if (auth == NULL) {
|
||||
parameters->shareKeyId = prevShareKeyId;
|
||||
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
|
||||
return BSL_MALLOC_FAIL;
|
||||
}
|
||||
auth->sca_keylength = SCTP_SHARED_AUTHKEY_LEN;
|
||||
auth->sca_keynumber = key->shareKeyId;
|
||||
(void)memcpy_s(&auth->sca_key[0], SCTP_SHARED_AUTHKEY_LEN, authKey, size);
|
||||
int32_t ret = AddAuthKey(uio, parameters, auth, optLen, prevShareKeyId);
|
||||
BSL_SAL_Free(auth);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t CheckArgsAvalid(const void *parg, int32_t larg)
|
||||
{
|
||||
if (parg == NULL || larg != sizeof(uint16_t)) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05063, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"invalid args", 0, 0, 0, 0);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BslSctpActiveAuthKey(BSL_UIO *uio, void *parg, int32_t larg)
|
||||
{
|
||||
int32_t ret = CheckArgsAvalid(parg, larg);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
SctpParameters *parameters = BSL_UIO_GetCtx(uio);
|
||||
uint16_t shareKeyId = *(uint16_t*)parg;
|
||||
/* Active shared key id */
|
||||
struct sctp_authkeyid authKeyId = {0};
|
||||
authKeyId.scact_keynumber = shareKeyId;
|
||||
int32_t fd = BSL_UIO_GetFd(uio);
|
||||
if (fd < 0) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
ret = BSL_SAL_SetSockopt(fd, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authKeyId, sizeof(struct sctp_authkeyid));
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_SAL_ERR_NET_SETSOCKOPT);
|
||||
return BSL_SAL_ERR_NET_SETSOCKOPT;
|
||||
}
|
||||
parameters->isAddAuthkey = false;
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05038, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio: SCTP active auth key(id:%u) success.", parameters->shareKeyId, 0, 0, 0);
|
||||
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BslSctpDelAuthKey(BSL_UIO *uio, void *parg, int32_t larg)
|
||||
{
|
||||
int32_t ret = CheckArgsAvalid(parg, larg);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
uint16_t delShareKeyId = *(uint16_t*)parg;
|
||||
int32_t fd = BSL_UIO_GetFd(uio);
|
||||
if (fd < 0) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
/* Delete old sharekey */
|
||||
struct sctp_authkeyid authKeyId = {0};
|
||||
authKeyId.scact_keynumber = delShareKeyId;
|
||||
ret = BSL_SAL_SetSockopt(fd, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, &authKeyId, sizeof(struct sctp_authkeyid));
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_SAL_ERR_NET_SETSOCKOPT);
|
||||
return BSL_SAL_ERR_NET_SETSOCKOPT;
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t BslSctpIsSndBuffEmpty(BSL_UIO *uio, void *parg, int32_t larg)
|
||||
{
|
||||
if (parg == NULL || larg != sizeof(uint8_t)) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05064, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"get sctp status failed", 0, 0, 0, 0);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
|
||||
int32_t fd = BSL_UIO_GetFd(uio);
|
||||
if (fd < 0) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
|
||||
struct sctp_status status = {0};
|
||||
uint32_t statusLen = sizeof(status);
|
||||
int32_t ret = BSL_SAL_GetSockopt(fd, IPPROTO_SCTP, SCTP_STATUS, &status, &statusLen);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_SAL_ERR_NET_GETSOCKOPT);
|
||||
return BSL_SAL_ERR_NET_GETSOCKOPT;
|
||||
}
|
||||
|
||||
uint8_t *isEmpty = (uint8_t *)parg;
|
||||
*isEmpty = false;
|
||||
|
||||
if (status.sstat_unackdata == 0) {
|
||||
*isEmpty = true;
|
||||
}
|
||||
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t SctpCtrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg)
|
||||
{
|
||||
if (uio->ctx == NULL) {
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
SctpParameters *parameters = BSL_UIO_GetCtx(uio);
|
||||
switch (cmd) {
|
||||
case BSL_UIO_SET_PEER_IP_ADDR:
|
||||
return BslSctpSetPeerIpAddr(parameters, parg, (uint32_t)larg);
|
||||
case BSL_UIO_GET_PEER_IP_ADDR:
|
||||
return BslSctpGetPeerIpAddr(parameters, parg, larg);
|
||||
case BSL_UIO_SCTP_GET_SEND_STREAM_ID:
|
||||
return BslSctpGetSendStreamId(uio, parg, larg);
|
||||
case BSL_UIO_SCTP_SET_APP_STREAM_ID:
|
||||
return BslSctpSetAppStreamId(parameters, parg, larg);
|
||||
case BSL_UIO_SET_FD:
|
||||
return BslSctpSetFd(uio, larg, parg);
|
||||
case BSL_UIO_GET_FD:
|
||||
return BslSctpGetFd(parameters, parg, larg);
|
||||
case BSL_UIO_SCTP_MARK_APP_MESSAGE:
|
||||
return BslSctpMaskAppMsg(parameters, parg, larg);
|
||||
case BSL_UIO_SCTP_CHECK_PEER_AUTH:
|
||||
return BslSctpCheckPeerAuth(uio, parg, larg);
|
||||
case BSL_UIO_SCTP_ADD_AUTH_SHARED_KEY:
|
||||
return BslSctpAddAuthKey(uio, parg, larg);
|
||||
case BSL_UIO_SCTP_ACTIVE_AUTH_SHARED_KEY:
|
||||
return BslSctpActiveAuthKey(uio, ¶meters->shareKeyId, sizeof(parameters->shareKeyId));
|
||||
case BSL_UIO_SCTP_DEL_PRE_AUTH_SHARED_KEY:
|
||||
return BslSctpDelAuthKey(uio, ¶meters->prevShareKeyId, sizeof(parameters->shareKeyId));
|
||||
case BSL_UIO_SCTP_SND_BUFF_IS_EMPTY:
|
||||
return BslSctpIsSndBuffEmpty(uio, parg, larg);
|
||||
default:
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
|
||||
return BSL_UIO_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t SctpWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen)
|
||||
{
|
||||
/* set flags */
|
||||
const uint32_t flags = SCTP_SACK_IMMEDIATELY;
|
||||
uint16_t sendStreamId = 0;
|
||||
int32_t ret = BSL_UIO_Ctrl(uio, BSL_UIO_SCTP_GET_SEND_STREAM_ID, sizeof(sendStreamId), &sendStreamId);
|
||||
if (ret != BSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
int32_t fd = BSL_UIO_GetFd(uio);
|
||||
if (fd < 0) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
ret = sctp_sendmsg(fd, buf, len, NULL, 0, 0, flags, sendStreamId, 0, 0);
|
||||
if (ret <= 0) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
*writeLen = ret;
|
||||
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t SctpRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen)
|
||||
{
|
||||
*readLen = 0;
|
||||
SctpParameters *parameters = BSL_UIO_GetCtx(uio);
|
||||
if (parameters == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
|
||||
if (BSL_UIO_Ctrl(uio, BSL_UIO_SCTP_CHECK_PEER_AUTH, sizeof(parameters->peerAuthed), ¶meters->peerAuthed) !=
|
||||
BSL_SUCCESS ||
|
||||
parameters->peerAuthed == false) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05032, BSL_LOG_LEVEL_DEBUG, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio:Check SCTP Peer Auth ERROR.", 0, 0, 0, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
|
||||
struct sctp_sndrcvinfo sinfo;
|
||||
int32_t flags = 0;
|
||||
int32_t fd = BSL_UIO_GetFd(uio);
|
||||
if (fd < 0) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
int32_t ret = sctp_recvmsg(fd, buf, len, NULL, NULL, &sinfo, &flags);
|
||||
if (ret <= 0) {
|
||||
if (UioIsNonFatalErr(errno) == true) {
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
|
||||
*readLen = ret;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
const BSL_UIO_Method *BSL_UIO_SctpMethod(void)
|
||||
{
|
||||
static const BSL_UIO_Method method = {
|
||||
BSL_UIO_SCTP,
|
||||
SctpWrite,
|
||||
SctpRead,
|
||||
SctpCtrl,
|
||||
NULL,
|
||||
NULL,
|
||||
SctpNew,
|
||||
SctpDestroy
|
||||
};
|
||||
return &method;
|
||||
}
|
||||
#endif /* HITLS_BSL_UIO_SCTP */
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef UIO_SCTP_H
|
||||
#define UIO_SCTP_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_UIO_SCTP
|
||||
|
||||
#include "bsl_uio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DTLS_SCTP_SHARE_AUTHKEY_ID_MAX 65535
|
||||
|
||||
int32_t SctpWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen);
|
||||
int32_t SctpRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_BSL_UIO_SCTP */
|
||||
|
||||
#endif // UIO_SCTP_H
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_UIO_TCP
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bsl_binlog_id.h"
|
||||
#include "bsl_err_internal.h"
|
||||
#include "bsl_log_internal.h"
|
||||
#include "bsl_log.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_errno.h"
|
||||
#include "sal_net.h"
|
||||
#include "uio_base.h"
|
||||
#include "uio_abstraction.h"
|
||||
#include "uio_tcp.h"
|
||||
|
||||
typedef struct {
|
||||
int32_t fd;
|
||||
} TcpPrameters;
|
||||
|
||||
static int32_t TcpNew(BSL_UIO *uio)
|
||||
{
|
||||
if (uio->ctx != NULL) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05056, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio: ctx is already existed.", 0, 0, 0, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
|
||||
return BSL_UIO_FAIL;
|
||||
}
|
||||
|
||||
TcpPrameters *parameters = (TcpPrameters *)BSL_SAL_Calloc(1u, sizeof(TcpPrameters));
|
||||
if (parameters == NULL) {
|
||||
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05057, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
|
||||
"Uio: tcp param malloc fail.", 0, 0, 0, 0);
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
|
||||
return BSL_UIO_FAIL;
|
||||
}
|
||||
|
||||
parameters->fd = -1;
|
||||
uio->ctx = parameters;
|
||||
uio->ctxLen = sizeof(TcpPrameters);
|
||||
// Specifies whether to be closed by uio when setting fd.
|
||||
// The default value of init is 0. Set the value of init to 1 after the fd is set.
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t TcpSocketDestroy(BSL_UIO *uio)
|
||||
{
|
||||
if (uio == NULL) {
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
uio->init = 0;
|
||||
TcpPrameters *ctx = BSL_UIO_GetCtx(uio);
|
||||
if (ctx != NULL) {
|
||||
if (BSL_UIO_GetIsUnderlyingClosedByUio(uio) && ctx->fd != -1) {
|
||||
(void)BSL_SAL_SockClose(ctx->fd);
|
||||
}
|
||||
BSL_SAL_FREE(ctx);
|
||||
BSL_UIO_SetCtx(uio, NULL);
|
||||
}
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t TcpWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen)
|
||||
{
|
||||
*writeLen = 0;
|
||||
return uio->method.write(uio, buf, len, writeLen);
|
||||
}
|
||||
|
||||
int32_t TcpRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen)
|
||||
{
|
||||
*readLen = 0;
|
||||
return uio->method.read(uio, buf, len, readLen);
|
||||
}
|
||||
|
||||
static int32_t TcpSocketWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen)
|
||||
{
|
||||
*writeLen = 0;
|
||||
int32_t err = 0;
|
||||
int32_t fd = BSL_UIO_GetFd(uio);
|
||||
if (fd < 0) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
ssize_t ret = BSL_SAL_Write(fd, buf, len, &err);
|
||||
(void)BSL_UIO_ClearFlags(uio, BSL_UIO_FLAGS_RWS | BSL_UIO_FLAGS_SHOULD_RETRY);
|
||||
if (ret > 0) {
|
||||
*writeLen = (uint32_t)ret;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
// If the value of ret is less than or equal to 0, check errno first.
|
||||
if (UioIsNonFatalErr(err)) { // Indicates the errno for determining whether retry is allowed.
|
||||
(void)BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_WRITE | BSL_UIO_FLAGS_SHOULD_RETRY);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
|
||||
static int32_t TcpSocketRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen)
|
||||
{
|
||||
*readLen = 0;
|
||||
|
||||
int32_t err = 0;
|
||||
(void)BSL_UIO_ClearFlags(uio, BSL_UIO_FLAGS_RWS | BSL_UIO_FLAGS_SHOULD_RETRY);
|
||||
int32_t fd = BSL_UIO_GetFd(uio);
|
||||
if (fd < 0) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
ssize_t ret = BSL_SAL_Read(fd, buf, len, &err);
|
||||
if (ret > 0) { // Success
|
||||
*readLen = (uint32_t)ret;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
// If the value of ret is less than or equal to 0, check errno first.
|
||||
if (UioIsNonFatalErr(err)) { // Indicates the errno for determining whether retry is allowed.
|
||||
(void)BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_READ | BSL_UIO_FLAGS_SHOULD_RETRY);
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
if (ret == 0) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EOF);
|
||||
return BSL_UIO_IO_EOF;
|
||||
}
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_IO_EXCEPTION);
|
||||
return BSL_UIO_IO_EXCEPTION;
|
||||
}
|
||||
|
||||
static int32_t TcpSetFd(BSL_UIO *uio, int32_t size, const int32_t *fd)
|
||||
{
|
||||
bool invalid = (fd == NULL) || (uio == NULL);
|
||||
if (invalid) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
if (size != (int32_t)sizeof(*fd)) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
TcpPrameters *ctx = BSL_UIO_GetCtx(uio);
|
||||
if (ctx == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
if (ctx->fd != -1) {
|
||||
if (BSL_UIO_GetIsUnderlyingClosedByUio(uio)) {
|
||||
(void)BSL_SAL_SockClose(ctx->fd);
|
||||
}
|
||||
}
|
||||
ctx->fd = *fd;
|
||||
uio->init = 1;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t TcpGetFd(BSL_UIO *uio, int32_t size, int32_t *fd)
|
||||
{
|
||||
bool invalid = uio == NULL || fd == NULL;
|
||||
if (invalid) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
if (size != (int32_t)sizeof(*fd)) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
|
||||
return BSL_INVALID_ARG;
|
||||
}
|
||||
TcpPrameters *ctx = BSL_UIO_GetCtx(uio);
|
||||
if (ctx == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
*fd = ctx->fd;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t TcpSocketCtrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case BSL_UIO_SET_FD:
|
||||
return TcpSetFd(uio, larg, parg);
|
||||
case BSL_UIO_GET_FD:
|
||||
return TcpGetFd(uio, larg, parg);
|
||||
case BSL_UIO_FLUSH:
|
||||
return BSL_SUCCESS;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
|
||||
return BSL_UIO_FAIL;
|
||||
}
|
||||
|
||||
const BSL_UIO_Method *BSL_UIO_TcpMethod(void)
|
||||
{
|
||||
static const BSL_UIO_Method method = {
|
||||
BSL_UIO_TCP,
|
||||
TcpSocketWrite,
|
||||
TcpSocketRead,
|
||||
TcpSocketCtrl,
|
||||
NULL,
|
||||
NULL,
|
||||
TcpNew,
|
||||
TcpSocketDestroy
|
||||
};
|
||||
return &method;
|
||||
}
|
||||
|
||||
#endif /* HITLS_BSL_UIO_TCP */
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef UIO_TCP_H
|
||||
#define UIO_TCP_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_UIO_TCP
|
||||
|
||||
#include "bsl_uio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int32_t TcpWrite(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen);
|
||||
int32_t TcpRead(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_BSL_UIO_TCP */
|
||||
|
||||
#endif // UIO_TCP_H
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_BSL_USRDATA
|
||||
|
||||
#include <stddef.h>
|
||||
#include "bsl_errno.h"
|
||||
#include "bsl_err_internal.h"
|
||||
#include "bsl_user_data.h"
|
||||
|
||||
typedef struct {
|
||||
long argl; /* Arbitrary long */
|
||||
void *argp; /* Arbitrary void * */
|
||||
BSL_USER_ExDataNew *newFunc;
|
||||
BSL_USER_ExDataFree *freeFunc;
|
||||
BSL_USER_ExDataDup *dupFunc;
|
||||
} BSL_EX_CALLBACK;
|
||||
|
||||
BSL_EX_CALLBACK g_exCallBack[BSL_MAX_EX_TYPE][BSL_MAX_EX_DATA];
|
||||
|
||||
int BSL_USER_GetExDataNewIndex(int32_t index, int64_t argl, const void *argp, void *newFunc, void *dupFunc,
|
||||
void *freeFunc)
|
||||
{
|
||||
if (index < 0 || index >= BSL_MAX_EX_TYPE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
(void)argl;
|
||||
(void)argp;
|
||||
(void)newFunc;
|
||||
(void)dupFunc;
|
||||
// The preceding parameters will not be used. Only the freefunc will be used.
|
||||
static int idxSsl = 1; // The index starts from 1, 0 indicates app data.
|
||||
static int idxX509StoreCtx = 1;
|
||||
static int idxSslCtx = 1;
|
||||
static int idxX509Store = 1;
|
||||
static int idxUio = 1;
|
||||
int idx = -1;
|
||||
switch (index) {
|
||||
case BSL_USER_DATA_EX_INDEX_SSL:
|
||||
idx = idxSsl++;
|
||||
break;
|
||||
case BSL_USER_DATA_EX_INDEX_X509_STORE_CTX:
|
||||
idx = idxX509StoreCtx++;
|
||||
break;
|
||||
case BSL_USER_DATA_EX_INDEX_SSL_CTX:
|
||||
idx = idxSslCtx++;
|
||||
break;
|
||||
case BSL_USER_DATA_EX_INDEX_X509_STORE:
|
||||
idx = idxX509Store++;
|
||||
break;
|
||||
case BSL_USER_DATA_EX_INDEX_UIO:
|
||||
idx = idxUio++;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (idx != -1 && idx < BSL_MAX_EX_DATA) {
|
||||
g_exCallBack[index][idx].freeFunc = freeFunc;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
int BSL_USER_SetExData(BSL_USER_ExData *ad, int32_t idx, void *val)
|
||||
{
|
||||
if (ad == NULL || idx >= BSL_MAX_EX_DATA || idx < 0) {
|
||||
BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
|
||||
return BSL_NULL_INPUT;
|
||||
}
|
||||
ad->sk[idx] = val;
|
||||
return BSL_SUCCESS;
|
||||
}
|
||||
|
||||
void *BSL_USER_GetExData(const BSL_USER_ExData *ad, int32_t idx)
|
||||
{
|
||||
if (ad == NULL || idx >= BSL_MAX_EX_DATA || idx < 0) {
|
||||
return NULL;
|
||||
}
|
||||
return ad->sk[idx];
|
||||
}
|
||||
|
||||
void BSL_USER_FreeExDataIndex(int32_t index, void *obj, BSL_USER_ExData *ad)
|
||||
{
|
||||
if (index < 0 || index >= BSL_MAX_EX_TYPE || ad == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < BSL_MAX_EX_DATA; i++) {
|
||||
if (ad->sk[i] != NULL && g_exCallBack[index][i].freeFunc != NULL) {
|
||||
g_exCallBack[index][i].freeFunc(obj, ad->sk[i], ad, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif /* HITLS_BSL_USRDATA */
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"compileFlag": {
|
||||
"CC_OPT_LEVEL": [
|
||||
"-D_FORTIFY_SOURCE=2",
|
||||
"-O2"
|
||||
],
|
||||
"CC_OVERALL_FLAGS": ["-pipe"],
|
||||
"CC_WARN_FLAGS": [
|
||||
"-Werror",
|
||||
"-Wextra",
|
||||
"-Wall",
|
||||
"-Wdate-time",
|
||||
"-Wfloat-equal",
|
||||
"-Wshadow",
|
||||
"-Wformat=2"
|
||||
],
|
||||
"CC_LANGUAGE_FLAGS": [
|
||||
"-fsigned-char"
|
||||
],
|
||||
"CC_CDG_FLAGS": ["-fno-common"],
|
||||
"CC_MD_DEPENDENT_FLAGS": [],
|
||||
"CC_OPT_FLAGS": [
|
||||
"-fno-strict-aliasing",
|
||||
"-fno-omit-frame-pointer"
|
||||
],
|
||||
"CC_SEC_FLAGS": [
|
||||
"-fPIC",
|
||||
"-fstack-protector-strong",
|
||||
"--param=ssp-buffer-size=4"
|
||||
],
|
||||
"CC_DEFINE_FLAGS": [],
|
||||
"CC_DEBUG_FLAGS": [],
|
||||
"CC_USER_DEFINE_FLAGS": []
|
||||
},
|
||||
"linkFlag": {
|
||||
"PUBLIC": [
|
||||
"-shared",
|
||||
"-Wl,-z,noexecstack",
|
||||
"-Wl,-z,relro",
|
||||
"-Wl,-z,now",
|
||||
"-Wl,--build-id=none"
|
||||
],
|
||||
"SHARED": [],
|
||||
"EXE": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
{
|
||||
"compileFlag": {
|
||||
"CC_LANGUAGE_FLAGS": [
|
||||
"-std=c90",
|
||||
"-std=c99",
|
||||
"-std=c11",
|
||||
"-std=gnu90",
|
||||
"-std=gnu99",
|
||||
"-std=gnu11",
|
||||
"-Wpedantic",
|
||||
"-pedantic",
|
||||
"-pedantic-errors",
|
||||
"-fsigned-char",
|
||||
"-funsigned-char",
|
||||
"-fno-builtin",
|
||||
"-fno-builtin-bcmp",
|
||||
"-ffreestanding",
|
||||
"-fdisable-tree-widening_mul"
|
||||
],
|
||||
"CC_WARN_FLAGS": [
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Werror",
|
||||
"-Wtrampolines",
|
||||
"-Wformat=2",
|
||||
"-Wstrict-prototypes",
|
||||
"-Wdate-time",
|
||||
"-Wfloat-equal",
|
||||
"-Wswitch-default",
|
||||
"-Wshadow",
|
||||
"-Wstack-usage=8192",
|
||||
"-Wframe-larger-than=4096",
|
||||
"-Wconversion",
|
||||
"-Wcast-qual",
|
||||
"-Wcast-align",
|
||||
"-Wvla",
|
||||
"-Wunused",
|
||||
"-Wundef",
|
||||
"-Wnon-virtual-dtor",
|
||||
"-Wdelete-non-virtual-dtor",
|
||||
"-Woverloaded-virtual",
|
||||
"-Wredundant-decls",
|
||||
"-Wfloat-conversion",
|
||||
"-Wdisabled-optimization",
|
||||
"-Wduplicated-branches",
|
||||
"-Wduplicated-cond",
|
||||
"-Wjump-misses-init",
|
||||
"-Wlogical-op",
|
||||
"-Wmissing-format-attribute",
|
||||
"-Wmissing-include-dirs",
|
||||
"-Wmissing-prototypes",
|
||||
"-Wmissing-declarations",
|
||||
"-Wnested-externs",
|
||||
"-Wpointer-arith",
|
||||
"-Wshift-overflow=2",
|
||||
"-Wshift-overflow",
|
||||
"-Wshift-negative-value",
|
||||
"-Wsuggest-attribute=format",
|
||||
"-Wunused-macros",
|
||||
"-Wunused-parameter",
|
||||
"-Wunused-function",
|
||||
"-Wunused-label",
|
||||
"-Wunused-local-typedefs",
|
||||
"-Wunused-but-set-parameter",
|
||||
"-Wunused-but-set-variable",
|
||||
"-Wuninitialized",
|
||||
"-Wunused-variable",
|
||||
"-Wunused-value",
|
||||
"-Wwrite-strings",
|
||||
"-Wbad-function-cast",
|
||||
"-Wold-style-definition",
|
||||
"-Wsign-conversion",
|
||||
"-Wsign-compare",
|
||||
"-Winline",
|
||||
"-Wclobbered",
|
||||
"-Wempty-body",
|
||||
"-Woverride-init",
|
||||
"-Wformat-security",
|
||||
"-Wignored-qualifiers",
|
||||
"-Wimplicit-fallthrough=3",
|
||||
"-Wtype-limits",
|
||||
"-Wno-stringop-overread"
|
||||
],
|
||||
"CC_SEC_FLAGS": [
|
||||
"-fPIC",
|
||||
"-fPIE",
|
||||
"-fno-PIE",
|
||||
"-fstack-protector-all",
|
||||
"-fstack-protector-strong",
|
||||
"-fstack-check",
|
||||
"-ftrapv",
|
||||
"--param=ssp-buffer-size=4",
|
||||
"-fno-stack-protector",
|
||||
"-fsanitize=address",
|
||||
"-fprofile-arcs",
|
||||
"-ftest-coverage",
|
||||
"-fdump-rtl-expand",
|
||||
"-fsanitize=fuzzer-no-link",
|
||||
"-fsanitize=thread",
|
||||
"-fsanitize=undefined",
|
||||
"-fno-sanitize-recover=all",
|
||||
"-fsanitize=signed-integer-overflow",
|
||||
"-fsanitize-address-use-after-scope",
|
||||
"-fsanitize-coverage=trace-pc",
|
||||
"-fsanitize-coverage=trace-cmp",
|
||||
"-fsanitize-coverage=trace-div",
|
||||
"-fsanitize-coverage=trace-gep",
|
||||
"-fgnu89-inline"
|
||||
],
|
||||
"CC_OPT_LEVEL": [
|
||||
"-D_FORTIFY_SOURCE=2",
|
||||
"-O0",
|
||||
"-O1",
|
||||
"-O2",
|
||||
"-Os",
|
||||
"-Oz"
|
||||
],
|
||||
"CC_OPT_FLAGS": [
|
||||
"-fno-strict-aliasing",
|
||||
"-fno-omit-frame-pointer",
|
||||
"-fomit-frame-pointer",
|
||||
"-fno-early-inlining",
|
||||
"-fno-indirect-inlining",
|
||||
"-fno-inline-functions-called-once",
|
||||
"-fno-inline-small-functions",
|
||||
"-fno-function-sections",
|
||||
"-fno-inline"
|
||||
],
|
||||
"CC_CDG_FLAGS": [
|
||||
"-fno-common",
|
||||
"-freg-struct-return",
|
||||
"-fvisibility=hidden",
|
||||
"-fstrong-eval-order",
|
||||
"-fpack-struct=4",
|
||||
"-fno-exceptions",
|
||||
"-fno-delete-null-pointer-checks",
|
||||
"-fno-merge-constants",
|
||||
"-fpack-struct=4"
|
||||
],
|
||||
"CC_OVERALL_FLAGS": [
|
||||
"-pipe"
|
||||
],
|
||||
"CC_MD_DEPENDENT_FLAGS": [
|
||||
"-m32",
|
||||
"-m64",
|
||||
"-mabi=ilp32",
|
||||
"-march=armv7-a",
|
||||
"-march=armv8-a",
|
||||
"-mbig-endian",
|
||||
"-mtune=cortex-a57",
|
||||
"-mcpu=cortex-a15",
|
||||
"-mcpu=cortex-a9",
|
||||
"-mfloat-abi=softfp",
|
||||
"-mfpu=vfpv3-d16",
|
||||
"-mlittle-endian",
|
||||
"-mno-sched-prolog",
|
||||
"-mno-unaligned-access",
|
||||
"-mfloat-abi=soft",
|
||||
"-msoft-float",
|
||||
"-mtune=cortex-a15",
|
||||
"-mtune=cortex-a9",
|
||||
"-ffixed-r8",
|
||||
"-marm",
|
||||
"-mabi=aapcs-linux",
|
||||
"-mno-thumb-interwork",
|
||||
"--target=aarch64_be-unknown-linux-gnu_ilp32"
|
||||
],
|
||||
"CC_DEFINE_FLAGS": [
|
||||
"-DHITLS_SIXTY_FOUR_BITS",
|
||||
"-DHITLS_THIRTY_TWO_BITS",
|
||||
"-DHITLS_BSL_SAL_LINUX"
|
||||
],
|
||||
"CC_DEBUG_FLAGS": [
|
||||
"-g",
|
||||
"-g3",
|
||||
"-gdwarf-2"
|
||||
],
|
||||
"CC_USER_DEFINE_FLAGS": [
|
||||
"-DHITLS_CRYPTO_DRBG_GM_LEVEL=n",
|
||||
"-DHITLS_EAL_INIT_OPTS=n"
|
||||
]
|
||||
},
|
||||
"linkFlag": {
|
||||
"PUBLIC": [
|
||||
"-Wl,-z,relro",
|
||||
"-Wl,-z,now",
|
||||
"-Wl,-z,relro,-z,now",
|
||||
"-Wl,-z,noexecstack",
|
||||
"-s",
|
||||
"-rdynamic",
|
||||
"-Wl,--build-id=none"
|
||||
],
|
||||
"SHARED": [
|
||||
"-shared"
|
||||
],
|
||||
"EXE": [
|
||||
"-pie"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,715 @@
|
||||
{
|
||||
"libs":{
|
||||
"hitls_bsl": {
|
||||
"features": {
|
||||
"c": {
|
||||
"err": null,
|
||||
"hash": null,
|
||||
"init": {"deps": ["err"]},
|
||||
"base64": null,
|
||||
"pem": null,
|
||||
"list": null,
|
||||
"log": null,
|
||||
"obj":null,
|
||||
"sal": null,
|
||||
"sal_mem": null,
|
||||
"sal_thread": null,
|
||||
"sal_lock": null,
|
||||
"sal_time": null,
|
||||
"sal_file": null,
|
||||
"sal_net": null,
|
||||
"sal_str": null,
|
||||
"tlv": null,
|
||||
"uio_plt": null,
|
||||
"uio": {
|
||||
"uio_plt": null,
|
||||
"uio_buffer": {"deps": ["uio_plt"]},
|
||||
"uio_sctp": {"deps": ["uio_plt", "sal_net"]},
|
||||
"uio_tcp": {"deps": ["uio_plt", "sal_net"]}
|
||||
},
|
||||
"usrdata": null,
|
||||
"asn1":null
|
||||
}
|
||||
}
|
||||
},
|
||||
"hitls_crypto":{
|
||||
"lang": "C ASM",
|
||||
"features": {
|
||||
"c": {
|
||||
"eal": {"deps": ["init"]},
|
||||
"ealinit": null,
|
||||
"md": {
|
||||
"md5": null,
|
||||
"sm3": null,
|
||||
"sha1": null,
|
||||
"sha2": {
|
||||
"sha224": null,
|
||||
"sha256": null,
|
||||
"sha384": null,
|
||||
"sha512": null
|
||||
},
|
||||
"sha3": null
|
||||
},
|
||||
"mac": {
|
||||
"hmac": null
|
||||
},
|
||||
"kdf": {
|
||||
"scrypt": {"deps": ["sha256", "pbkdf2"]},
|
||||
"hkdf": null,
|
||||
"pbkdf2": null,
|
||||
"kdftls12": null,
|
||||
"deps": ["hmac"]
|
||||
},
|
||||
"drbg": {
|
||||
"drbg_hash": null,
|
||||
"drbg_hmac": {"deps": ["hmac"]},
|
||||
"drbg_ctr": {"deps": ["aes"]}
|
||||
},
|
||||
"entropy": {
|
||||
"opts": ["drbg", "drbg_hash", "drbg_hmac", "drbg_ctr"]
|
||||
},
|
||||
"modes": {
|
||||
"cbc": null,
|
||||
"xts": null,
|
||||
"ctr": null,
|
||||
"ofb": null,
|
||||
"cfb": null,
|
||||
"ccm": null,
|
||||
"gcm": null,
|
||||
"chacha20poly1305": null
|
||||
},
|
||||
"cipher": {
|
||||
"aes": null,
|
||||
"sm4": null,
|
||||
"chacha20": {"deps": ["chacha20poly1305"]}
|
||||
},
|
||||
"ecc": {"deps": ["bn"]},
|
||||
"pkey": {
|
||||
"ecc": {"deps": ["bn"]},
|
||||
"rsa": {"deps": ["bn"]},
|
||||
"dsa": {"deps": ["bn"]},
|
||||
"dh": {"deps": ["bn"]},
|
||||
"paillier": {"deps":["bn"]},
|
||||
"ecdh": {"deps": ["ecc"]},
|
||||
"ecdsa": {"deps": ["ecc"]},
|
||||
"curve25519": {
|
||||
"ed25519": {"deps": ["sha512"]},
|
||||
"x25519": null
|
||||
},
|
||||
"sm2": {
|
||||
"sm2_crypt": null,
|
||||
"sm2_sign": null,
|
||||
"sm2_exch": null,
|
||||
"deps": ["ecc", "sm3"]
|
||||
}
|
||||
},
|
||||
"bn": null
|
||||
},
|
||||
"x8664": {
|
||||
"sha1": {"ins_set":["x8664", "avx512"]},
|
||||
"sha2": {"ins_set":["x8664", "avx512"]},
|
||||
"md5": {"ins_set":["x8664", "avx512"]},
|
||||
"sm3": null,
|
||||
"modes": {"ins_set":["x8664", "avx512"]},
|
||||
"aes": {"ins_set":["x8664", "avx512"]},
|
||||
"sm4": {"ins_set":["x8664", "avx512"]},
|
||||
"ecc": {"ins_set":["x8664", "avx512"]}
|
||||
},
|
||||
"armv8": {
|
||||
"sm3": null,
|
||||
"aes": null,
|
||||
"chacha20": null,
|
||||
"sm4": null,
|
||||
"ecc": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"hitls_tls": {
|
||||
"Note": "Currently, hitls_tls does not support feature division. 'all_tls' is a temporary solution.",
|
||||
"features": {
|
||||
"c": {
|
||||
"all_tls": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"hitls_x509":{
|
||||
"lang" : "C",
|
||||
"features" : {
|
||||
"c": {
|
||||
"all_x509" : null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules":{
|
||||
"crypto":{
|
||||
"eal": {
|
||||
".features": ["eal"],
|
||||
".srcs": "crypto/eal/src/*.c",
|
||||
".deps": ["bsl::sal"],
|
||||
".include": [
|
||||
"crypto/ealinit/include",
|
||||
"crypto/sha1/include",
|
||||
"crypto/sha2/include",
|
||||
"crypto/sha3/include",
|
||||
"crypto/md5/include",
|
||||
"crypto/sm3/include",
|
||||
"crypto/hmac/include",
|
||||
"crypto/scrypt/include",
|
||||
"crypto/hkdf/include",
|
||||
"crypto/kdf/include",
|
||||
"crypto/pbkdf2/include",
|
||||
"crypto/drbg/include",
|
||||
"crypto/entropy/include",
|
||||
"crypto/modes/include",
|
||||
"crypto/aes/include",
|
||||
"crypto/sm4/include",
|
||||
"crypto/chacha20/include",
|
||||
"crypto/bn/include",
|
||||
"crypto/encode/include",
|
||||
"crypto/ecc/include",
|
||||
"crypto/rsa/include",
|
||||
"crypto/dh/include",
|
||||
"crypto/dsa/include",
|
||||
"crypto/ecdsa/include",
|
||||
"crypto/ecdh/include",
|
||||
"crypto/curve25519/include",
|
||||
"crypto/sm2/include",
|
||||
"crypto/paillier/include"
|
||||
]
|
||||
},
|
||||
"ealinit": {
|
||||
".features": ["ealinit"],
|
||||
".srcs": "crypto/ealinit/src/*.c",
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"sha1": {
|
||||
".features": ["sha1"],
|
||||
".srcs": {
|
||||
"public":"crypto/sha1/src/sha1*.c",
|
||||
"no_asm": "crypto/sha1/src/noasm_*.c",
|
||||
"armv8": "crypto/sha1/src/asm/*_armv8.S",
|
||||
"x8664": {
|
||||
"x8664": "crypto/sha1/src/asm/*_x86_64.S",
|
||||
"avx512": "crypto/sha1/src/asm/*_x86_64.S"
|
||||
}
|
||||
},
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"sha2": {
|
||||
".features": ["sha224", "sha256", "sha384", "sha512"],
|
||||
".srcs": {
|
||||
"public": "crypto/sha2/src/sha2*.c",
|
||||
"no_asm": "crypto/sha2/src/noasm_*.c",
|
||||
"armv8": ["crypto/sha2/src/asm_*.c", "crypto/sha2/src/asm/*_armv8.S"],
|
||||
"x8664":{
|
||||
"x8664":["crypto/sha2/src/asm_*.c", "crypto/sha2/src/asm/*_x86_64.S"],
|
||||
"avx512":["crypto/sha2/src/asm_*.c", "crypto/sha2/src/asm/*_x86_64.S"]
|
||||
}
|
||||
},
|
||||
".deps": ["platform::Secure_C", "bsl::sal"]
|
||||
},
|
||||
"sha3": {
|
||||
".features": ["sha3"],
|
||||
".srcs": {
|
||||
"public":"crypto/sha3/src/sha3*.c",
|
||||
"no_asm": "crypto/sha3/src/noasm_*.c",
|
||||
"armv8": "crypto/sha3/src/asm/*_armv8.S"
|
||||
},
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"md5": {
|
||||
".features": ["md5"],
|
||||
".srcs": {
|
||||
"public":"crypto/md5/src/md5*.c",
|
||||
"no_asm": "crypto/md5/src/noasm_*.c",
|
||||
"x8664": {
|
||||
"x8664": "crypto/md5/src/asm/*_x86_64.S",
|
||||
"avx512": "crypto/md5/src/asm/*_x86_64.S"
|
||||
}
|
||||
},
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"sm3": {
|
||||
".features": ["sm3"],
|
||||
".srcs": {
|
||||
"public": "crypto/sm3/src/sm3_public.c",
|
||||
"no_asm": ["crypto/sm3/src/noasm_sm3.c"],
|
||||
"armv8": ["crypto/sm3/src/asm/*armv8.S", "crypto/sm3/src/asm_sm3.c"],
|
||||
"x8664": ["crypto/sm3/src/asm/*x86_64.s", "crypto/sm3/src/asm_sm3.c"]
|
||||
},
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"hmac": {
|
||||
".features": ["hmac"],
|
||||
".srcs": "crypto/hmac/src/*.c",
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"scrypt": {
|
||||
".features": ["scrypt"],
|
||||
".srcs": "crypto/scrypt/src/*.c",
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"hkdf": {
|
||||
".features": ["hkdf"],
|
||||
".srcs": "crypto/hkdf/src/*.c",
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"kdf": {
|
||||
".features": ["kdftls12"],
|
||||
".srcs": "crypto/kdf/src/*.c",
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"pbkdf2": {
|
||||
".features": ["pbkdf2"],
|
||||
".srcs": "crypto/pbkdf2/src/*.c",
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"modes": {
|
||||
".features": ["cbc", "xts", "ctr", "ofb", "cfb", "ccm", "gcm", "chacha20poly1305"],
|
||||
".srcs": {
|
||||
"public": "crypto/modes/src/modes*.c",
|
||||
"no_asm": "crypto/modes/src/noasm_*.c",
|
||||
"armv8": [
|
||||
"crypto/modes/src/noasm_poly1305.c",
|
||||
"crypto/modes/src/noasm_aes_gcm.c",
|
||||
"crypto/modes/src/asm_aes_cbc.c",
|
||||
"crypto/modes/src/asm_aes_ecb.c",
|
||||
"crypto/modes/src/asm_aes_ctr.c",
|
||||
"crypto/modes/src/asm/ghash_armv8.S",
|
||||
"crypto/modes/src/noasm_aes_ccm.c",
|
||||
"crypto/modes/src/asm_aes_cfb.c",
|
||||
"crypto/modes/src/asm_sm4_xts.c",
|
||||
"crypto/modes/src/asm_sm4_ecb.c",
|
||||
"crypto/modes/src/asm_sm4_cbc.c",
|
||||
"crypto/modes/src/asm_sm4_cfb.c",
|
||||
"crypto/modes/src/asm_sm4_ofb_armv8.c",
|
||||
"crypto/modes/src/asm_sm4_ctr.c",
|
||||
"crypto/modes/src/asm_sm4_setkey.c",
|
||||
"crypto/modes/src/asm_sm4_gcm.c"
|
||||
],
|
||||
"x8664": {
|
||||
"x8664":[
|
||||
"crypto/modes/src/asm_aes_ctr.c",
|
||||
"crypto/modes/src/noasm_aes_gcm.c",
|
||||
"crypto/modes/src/asm_aes_cbc.c",
|
||||
"crypto/modes/src/asm_aes_ecb.c",
|
||||
"crypto/modes/src/asm/ghash_x86_64.S",
|
||||
"crypto/modes/src/asm_aes_ccm.c",
|
||||
"crypto/modes/src/asm/aes_ccm_x86_64.S",
|
||||
"crypto/modes/src/noasm_poly1305.c",
|
||||
"crypto/modes/src/noasm_aes_cfb.c",
|
||||
"crypto/modes/src/asm_sm4_xts.c",
|
||||
"crypto/modes/src/asm_sm4_ecb.c",
|
||||
"crypto/modes/src/asm_sm4_cbc.c",
|
||||
"crypto/modes/src/asm_sm4_cfb.c",
|
||||
"crypto/modes/src/asm_sm4_ofb_x86_64.c",
|
||||
"crypto/modes/src/asm_sm4_ctr.c",
|
||||
"crypto/modes/src/asm_sm4_setkey.c",
|
||||
"crypto/modes/src/asm_sm4_gcm.c"
|
||||
],
|
||||
"avx512":[
|
||||
"crypto/modes/src/asm_aes_ctr.c",
|
||||
"crypto/modes/src/noasm_aes_gcm.c",
|
||||
"crypto/modes/src/asm_aes_cbc.c",
|
||||
"crypto/modes/src/asm_aes_ecb.c",
|
||||
"crypto/modes/src/asm/ghash_x86_64.S",
|
||||
"crypto/modes/src/asm_aes_ccm.c",
|
||||
"crypto/modes/src/asm/aes_ccm_x86_64.S",
|
||||
"crypto/modes/src/noasm_poly1305.c",
|
||||
"crypto/modes/src/noasm_aes_cfb.c",
|
||||
"crypto/modes/src/asm_sm4_xts.c"
|
||||
]
|
||||
}
|
||||
},
|
||||
".deps": ["bsl::sal"],
|
||||
".include": ["crypto/sm4/include", "crypto/aes/include"]
|
||||
},
|
||||
"aes": {
|
||||
".features": ["aes"],
|
||||
".srcs": {
|
||||
"no_asm":["crypto/aes/src/crypt_aes.c"],
|
||||
"public": "crypto/aes/src/crypt_aes_setkey.c",
|
||||
"armv8":[
|
||||
"crypto/aes/src/asm/crypt_aes_armv8.S",
|
||||
"crypto/aes/src/asm/crypt_aes_ecb_armv8.S",
|
||||
"crypto/aes/src/asm/crypt_aes_cbc_armv8.S",
|
||||
"crypto/aes/src/asm/crypt_aes_ctr_armv8.S",
|
||||
"crypto/aes/src/asm/crypt_aes_cfb_armv8.S"
|
||||
],
|
||||
"x8664": {
|
||||
"x8664": [
|
||||
"crypto/aes/src/asm/crypt_aes_x86_64.S",
|
||||
"crypto/aes/src/asm/crypt_aes_ecb_x86_64.S",
|
||||
"crypto/aes/src/asm/crypt_aes_cbc_x86_64.S",
|
||||
"crypto/aes/src/asm/crypt_aes_ctr_x86_64.S"
|
||||
],
|
||||
"avx512": [
|
||||
"crypto/aes/src/asm/crypt_aes_x86_64.S",
|
||||
"crypto/aes/src/asm/crypt_aes_ecb_x86_64.S",
|
||||
"crypto/aes/src/asm/crypt_aes_cbc_x86_64.S",
|
||||
"crypto/aes/src/asm/crypt_aes_ctr_x86_64.S"
|
||||
]
|
||||
}
|
||||
},
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"chacha20": {
|
||||
".features": ["chacha20"],
|
||||
".srcs": {
|
||||
"public": "crypto/chacha20/src/chacha20.c",
|
||||
"no_asm": "crypto/chacha20/src/chacha20block.c",
|
||||
"armv8": "crypto/chacha20/src/chacha20block.c"
|
||||
},
|
||||
".deps": ["bsl::sal"]
|
||||
},
|
||||
"sm4": {
|
||||
".features": ["sm4"],
|
||||
".srcs": {
|
||||
"public": [
|
||||
"crypto/sm4/src/crypt_sm4_public.c",
|
||||
"crypto/sm4/src/crypt_sm4.c",
|
||||
"crypto/sm4/src/sm4_key.c"
|
||||
],
|
||||
"no_asm":[
|
||||
"crypto/sm4/src/crypt_sm4.c",
|
||||
"crypto/sm4/src/sm4_key.c"
|
||||
],
|
||||
"armv8":[
|
||||
"crypto/sm4/src/asm/crypt_sm4_xts_armv8.S",
|
||||
"crypto/sm4/src/asm/crypt_sm4_armv8.S",
|
||||
"crypto/sm4/src/crypt_sm4_armv8.c"
|
||||
],
|
||||
"x8664":{
|
||||
"x8664":[
|
||||
"crypto/sm4/src/asm/crypt_sm4_macro_x86_64.s",
|
||||
"crypto/sm4/src/asm/crypt_sm4_setkey_x86_64.S",
|
||||
"crypto/sm4/src/asm/crypt_sm4_x86_64.S",
|
||||
"crypto/sm4/src/asm/crypt_sm4_xts_x86_64.S",
|
||||
"crypto/sm4/src/crypt_sm4_x86_64.c",
|
||||
"crypto/sm4/src/asm/crypt_sm4_modes_macro_x86_64.s",
|
||||
"crypto/sm4/src/asm/crypt_sm4_modes_x86_64.S"
|
||||
],
|
||||
"avx512":[
|
||||
"crypto/sm4/src/asm/crypt_sm4_macro_x86_64.s",
|
||||
"crypto/sm4/src/asm/crypt_sm4_setkey_x86_64.S",
|
||||
"crypto/sm4/src/asm/crypt_sm4_x86_64.S",
|
||||
"crypto/sm4/src/asm/crypt_sm4_xts_x86_64.S",
|
||||
"crypto/sm4/src/crypt_sm4_x86_64.c"
|
||||
]
|
||||
}
|
||||
},
|
||||
".deps": ["bsl::sal"]
|
||||
},
|
||||
"entropy":{
|
||||
".features": ["entropy"],
|
||||
".srcs": "crypto/entropy/src/*.c",
|
||||
".deps": ["bsl::sal"]
|
||||
},
|
||||
"drbg": {
|
||||
".features": ["drbg_hash", "drbg_hmac", "drbg_ctr"],
|
||||
".srcs": "crypto/drbg/src/*.c",
|
||||
".deps": ["bsl::sal"]
|
||||
},
|
||||
"bn": {
|
||||
".features": ["bn"],
|
||||
".srcs": {
|
||||
"public": [
|
||||
"crypto/bn/src/bn_*.c"
|
||||
],
|
||||
"no_asm": "crypto/bn/src/noasm_*.c"
|
||||
},
|
||||
".deps": ["bsl::sal"]
|
||||
},
|
||||
"rsa": {
|
||||
".features": ["rsa"],
|
||||
".srcs": "crypto/rsa/src/*.c",
|
||||
".deps" : ["crypto::bn"]
|
||||
},
|
||||
"curve25519": {
|
||||
".features": ["ed25519", "x25519"],
|
||||
".srcs": {
|
||||
"public": "crypto/curve25519/src/curve25519*.c",
|
||||
"no_asm": "crypto/curve25519/src/noasm_*.c"
|
||||
},
|
||||
".deps": ["platform::Secure_C", "bsl::sal"]
|
||||
},
|
||||
"dsa": {
|
||||
".features": ["dsa"],
|
||||
".srcs": "crypto/dsa/src/*.c",
|
||||
".deps": ["crypto::bn", "crypto::encode"]
|
||||
},
|
||||
"dh": {
|
||||
".features": ["dh"],
|
||||
".srcs": "crypto/dh/src/*.c",
|
||||
".deps": ["crypto::bn"]
|
||||
},
|
||||
"encode": {
|
||||
".features": ["dsa", "ecdsa", "sm2", "sm2_crypt", "sm2_sign", "sm2_exch"],
|
||||
".srcs": "crypto/encode/src/*.c",
|
||||
".deps": ["crypto::bn", "bsl::asn1", "bsl::pem", "crypto::ecc", "bsl::obj"]
|
||||
},
|
||||
"util": {
|
||||
".features": [
|
||||
"sha1", "sha224", "sha256", "sha384", "sha512",
|
||||
"bn",
|
||||
"drbg_hash", "drbg_hmac", "drbg_ctr",
|
||||
"rsa", "ed25519", "x25519"
|
||||
],
|
||||
".srcs": "crypto/util/*.c",
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"ecc": {
|
||||
".features": ["ecc"],
|
||||
".srcs": {
|
||||
"public": "crypto/ecc/src/ec*.c",
|
||||
"no_asm": "crypto/ecc/src/noasm_*.c",
|
||||
"armv8": ["crypto/ecc/src/asm_*.c", "crypto/ecc/src/asm64_ecp_nistp256.c", "crypto/ecc/src/asm/*armv8.S"],
|
||||
"x8664": {
|
||||
"x8664": ["crypto/ecc/src/asm_*.c", "crypto/ecc/src/asm64_ecp_nistp256.c", "crypto/ecc/src/asm/*_x86_64.S"],
|
||||
"avx512": ["crypto/ecc/src/asm_*.c", "crypto/ecc/src/asm64_ecp_nistp256.c", "crypto/ecc/src/asm/*_x86_64.S"]
|
||||
}
|
||||
},
|
||||
".deps": ["crypto::bn", "bsl::sal"]
|
||||
},
|
||||
"ecdh": {
|
||||
".features": ["ecdh"],
|
||||
".srcs": "crypto/ecdh/src/*.c",
|
||||
".deps": ["crypto::bn", "bsl::sal", "crypto::ecc"]
|
||||
},
|
||||
"ecdsa": {
|
||||
".features": ["ecdsa"],
|
||||
".srcs": "crypto/ecdsa/src/*.c",
|
||||
".deps": ["crypto::bn", "bsl::sal", "crypto::encode", "crypto::ecc"]
|
||||
},
|
||||
"sm2": {
|
||||
".features": ["sm2_crypt", "sm2_sign", "sm2_exch"],
|
||||
".srcs": "crypto/sm2/src/*.c",
|
||||
".deps": ["crypto::bn", "bsl::sal", "crypto::encode", "crypto::ecc"]
|
||||
},
|
||||
"paillier": {
|
||||
".features": ["paillier"],
|
||||
".srcs": "crypto/paillier/src/*.c",
|
||||
".deps": ["crypto::bn"]
|
||||
}
|
||||
},
|
||||
"bsl":{
|
||||
"log": {
|
||||
".features": ["log"],
|
||||
".srcs": "bsl/log/src/*.c",
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"sal": {
|
||||
".features": ["sal", "sal_mem", "sal_lock", "sal_thread", "sal_time", "sal_file", "sal_str"],
|
||||
".srcs": [
|
||||
"bsl/sal/src/*.c",
|
||||
"bsl/sal/src/linux/*.c"
|
||||
],
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"err": {
|
||||
".features": ["err"],
|
||||
".srcs": "bsl/err/src/*.c",
|
||||
".deps": ["platform::Secure_C", "bsl::sal"]
|
||||
},
|
||||
"tlv": {
|
||||
".features": ["tlv"],
|
||||
".srcs": "bsl/tlv/src/*.c",
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"list": {
|
||||
".features": ["list"],
|
||||
".srcs": "bsl/list/src/*.c",
|
||||
".deps": ["platform::Secure_C", "bsl::sal"]
|
||||
},
|
||||
"obj": {
|
||||
".features":["obj"],
|
||||
".srcs":"bsl/obj/src/*.c",
|
||||
".deps": ["platform::Secure_C", "bsl::sal"]
|
||||
},
|
||||
"base64": {
|
||||
".features": ["base64"],
|
||||
".srcs": "bsl/base64/src/*.c",
|
||||
".deps": ["platform::Secure_C", "bsl::sal"]
|
||||
},
|
||||
"pem": {
|
||||
".features": ["pem"],
|
||||
".srcs": "bsl/pem/src/*.c",
|
||||
".deps": ["platform::Secure_C", "bsl::sal", "bsl::base64"]
|
||||
},
|
||||
"hash": {
|
||||
".features": ["hash"],
|
||||
".srcs": "bsl/hash/src/*.c",
|
||||
".deps": ["platform::Secure_C"]
|
||||
},
|
||||
"uio": {
|
||||
".features": [
|
||||
"uio_plt", "uio", "uio_buffer", "uio_sctp", "uio_tcp"
|
||||
],
|
||||
".srcs": "bsl/uio/src/*.c",
|
||||
".deps": ["platform::Secure_C", "bsl::sal"]
|
||||
},
|
||||
"usrdata": {
|
||||
".features": ["usrdata"],
|
||||
".srcs": "bsl/usrdata/src/*.c"
|
||||
},
|
||||
"asn1": {
|
||||
".features": ["asn1"],
|
||||
".srcs": "bsl/asn1/src/*.c",
|
||||
".deps": ["bsl::sal"]
|
||||
},
|
||||
"init": {
|
||||
".features": ["init"],
|
||||
".srcs": "bsl/init/*.c"
|
||||
}
|
||||
},
|
||||
"platform": {
|
||||
"Secure_C": {
|
||||
}
|
||||
},
|
||||
"tls": {
|
||||
"cm": {
|
||||
".features": ["all_tls"],
|
||||
".srcs": "tls/cm/src/*.c",
|
||||
".deps": ["bsl::tlv", "tls::alert", "tls::handshake", "tls::ccs", "bsl::log", "tls::app", "tls::config"],
|
||||
".include": [
|
||||
"include",
|
||||
"tls/handshake/include",
|
||||
"tls/handshake/common/include",
|
||||
"tls/handshake/recv/include",
|
||||
"tls/handshake/send/include"
|
||||
]
|
||||
},
|
||||
"crypt": {
|
||||
".features": ["all_tls"],
|
||||
".srcs": "tls/crypt/crypt_adapt/*.c",
|
||||
".deps": ["platform::Secure_C", "bsl::log", "bsl::sal"]
|
||||
},
|
||||
"crypt_self": {
|
||||
".features": ["all_tls"],
|
||||
".srcs": "tls/crypt/crypt_self/*.c",
|
||||
".deps": ["tls::crypt", "crypto::eal"],
|
||||
".include": [
|
||||
"include"
|
||||
]
|
||||
},
|
||||
"cert": {
|
||||
".features": ["all_tls"],
|
||||
".srcs": "tls/cert/**/*.c",
|
||||
".deps": ["platform::Secure_C", "bsl::log", "bsl::sal"],
|
||||
".include": [
|
||||
"include",
|
||||
"include/tls",
|
||||
"include/bsl",
|
||||
"bsl/asn1/include",
|
||||
"x509/include",
|
||||
"x509/x509_cert/include",
|
||||
"x509/x509_common/include",
|
||||
"tls/cert/hitls_x509_adapt"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
".features": ["all_tls"],
|
||||
".srcs": "tls/config/src/*.c",
|
||||
".deps": ["platform::Secure_C", "bsl::log", "bsl::sal", "tls::cert", "tls::crypt"]
|
||||
|
||||
},
|
||||
"record": {
|
||||
".features": ["all_tls"],
|
||||
".srcs": "tls/record/src/*.c",
|
||||
".deps": ["platform::Secure_C", "bsl::log", "bsl::sal", "bsl::tlv", "bsl::uio", "tls::config", "tls::crypt"],
|
||||
".include": [
|
||||
"tls/handshake/include",
|
||||
"tls/handshake/common/include"
|
||||
]
|
||||
},
|
||||
"ccs": {
|
||||
".features": ["all_tls"],
|
||||
".srcs": "tls/ccs/src/*.c",
|
||||
".deps": ["platform::Secure_C", "bsl::log", "bsl::sal", "tls::record", "bsl::uio"],
|
||||
".include": [
|
||||
"tls/handshake/include"
|
||||
]
|
||||
},
|
||||
"alert": {
|
||||
".features": ["all_tls"],
|
||||
".srcs": "tls/alert/src/*.c",
|
||||
".deps": ["platform::Secure_C", "bsl::log", "bsl::sal", "tls::record"]
|
||||
},
|
||||
"handshake": {
|
||||
".features": ["all_tls"],
|
||||
".srcs": "tls/handshake/**/*.c",
|
||||
".include": [
|
||||
"tls/include",
|
||||
"tls/cert/include",
|
||||
"tls/crypt/include",
|
||||
"tls/record/include",
|
||||
"tls/handshake/common/include",
|
||||
"tls/handshake/pack/include",
|
||||
"tls/handshake/parse/include",
|
||||
"tls/handshake/recv/include",
|
||||
"tls/handshake/send/include",
|
||||
"tls/handshake/reass/include",
|
||||
"tls/handshake/cookie/include"
|
||||
],
|
||||
".deps": ["platform::Secure_C", "bsl::log", "bsl::sal", "bsl::tlv", "tls::cert", "tls::crypt", "tls::record", "tls::config"]
|
||||
},
|
||||
"app": {
|
||||
".features": ["all_tls"],
|
||||
".srcs": "tls/app/src/*.c",
|
||||
".deps": ["platform::Secure_C", "bsl::log", "bsl::sal", "tls::record"]
|
||||
},
|
||||
"feature": {
|
||||
".features": ["all_tls"],
|
||||
".srcs": "tls/feature/**/*.c",
|
||||
".deps": ["platform::Secure_C", "bsl::log", "bsl::sal", "bsl::err", "bsl::tlv", "bsl::hash", "bsl::uio", "tls::cm", "tls::crypt"],
|
||||
".include": [
|
||||
"include",
|
||||
"bsl/uio/src",
|
||||
"bsl/obj/include",
|
||||
"tls/cert/cert_adapt",
|
||||
"tls/handshake/parse/src",
|
||||
"tls/handshake/common/include"
|
||||
]
|
||||
}
|
||||
},
|
||||
"x509" : {
|
||||
"x509_cert": {
|
||||
".features" : ["all_x509"],
|
||||
".srcs" : "x509/x509_cert/src/*",
|
||||
".deps" : ["platform::Secure_C", "x509::x509_common", "crypto::encode", "bsl::sal", "bsl::asn1", "bsl::obj", "bsl::list"],
|
||||
".include": ["x509/x509_csr/include"]
|
||||
},
|
||||
"x509_crl" : {
|
||||
".features" : ["all_x509"],
|
||||
".srcs" : "x509/x509_crl/src/*",
|
||||
".deps" : ["platform::Secure_C", "x509::x509_common", "bsl::sal", "bsl::asn1", "bsl::obj", "bsl::list"]
|
||||
},
|
||||
"x509_common" : {
|
||||
".features" : ["all_x509"],
|
||||
".srcs" : "x509/x509_common/src/*",
|
||||
".deps" : ["platform::Secure_C", "bsl::sal", "bsl::asn1", "bsl::obj", "bsl::list", "bsl::pem", "crypto::encode"]
|
||||
},
|
||||
"x509_verify" : {
|
||||
".features" : ["all_x509"],
|
||||
".srcs" : "x509/x509_verify/src/*",
|
||||
".deps" : ["platform::Secure_C", "x509::x509_cert", "x509::x509_crl", "x509::x509_common"]
|
||||
},
|
||||
"x509_csr" : {
|
||||
".features" : ["all_x509"],
|
||||
".srcs" : "x509/x509_csr/src/*",
|
||||
".deps" : ["platform::Secure_C", "x509::x509_common", "bsl::sal", "bsl::asn1", "bsl::obj", "bsl::list"]
|
||||
},
|
||||
"pkcs12" : {
|
||||
".features" : ["all_x509"],
|
||||
".srcs" : "x509/pkcs12/src/*",
|
||||
".deps" : ["platform::Secure_C", "x509::x509_common", "crypto::encode", "bsl::sal", "bsl::asn1", "bsl::obj", "bsl::list", "x509::x509_cert", "x509::cms"]
|
||||
},
|
||||
"cms" : {
|
||||
".features" : ["all_x509"],
|
||||
".srcs" : "x509/cms/src/*",
|
||||
".deps" : ["platform::Secure_C", "crypto::encode"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef HITLS_BUILD_H
|
||||
#define HITLS_BUILD_H
|
||||
|
||||
#include "hitls_config_layer.h"
|
||||
#include "hitls_config_check.h"
|
||||
|
||||
#endif /* HITLS_BUILD_H */
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
/* Check the dependency of the configuration features. The check rules are as follows:
|
||||
* Non-deterministic feature dependency needs to be checked.
|
||||
* For example, feature a depends on feature b or c:
|
||||
* if feature a is defined, at least one of feature b and c must be defined.
|
||||
*/
|
||||
|
||||
#ifndef HITLS_CONFIG_CHECK_H
|
||||
#define HITLS_CONFIG_CHECK_H
|
||||
|
||||
#if defined(HITLS_BSL_SAL_MEM) || defined(HITLS_BSL_SAL_LOCK) || defined(HITLS_BSL_SAL_THREAD) || \
|
||||
defined(HITLS_BSL_SAL_TIME) || defined(HITLS_BSL_SAL_FILE) || defined(HITLS_BSL_SAL_NET) || \
|
||||
defined(HITLS_BSL_SAL_STR)
|
||||
#ifndef HITLS_BSL_SAL_LINUX
|
||||
#error "[HiTLS] sal_* only work with HITLS_BSL_SAL_LINUX."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_HMAC) && !defined(HITLS_CRYPTO_MD)
|
||||
#error "[HiTLS] The hmac must work with hash."
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_DRBG_HASH) && !defined(HITLS_CRYPTO_MD)
|
||||
#error "[HiTLS] The drbg_hash must work with hash."
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_ENTROPY) && !defined(HITLS_CRYPTO_DRBG)
|
||||
#error "[HiTLS] The entropy must work with at leaset one drbg algorithm."
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_PKEY) && !defined(HITLS_CRYPTO_MD)
|
||||
#error "[HiTLS] The pkey must work with hash."
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_BN) && !(defined(HITLS_THIRTY_TWO_BITS) || defined(HITLS_SIXTY_FOUR_BITS))
|
||||
#error "[HiTLS] To use bn, the number of system bits must be specified first."
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_CONFIG_CHECK_H */
|
||||
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
/* Derivation of configuration features.
|
||||
* The derivation type (rule) and sequence are as follows:
|
||||
* 1. Parent features derive child features.
|
||||
* 2. Derive the features of dependencies.
|
||||
* For example, if feature a depends on features b and c, you need to derive features b and c.
|
||||
* 3. Child features derive parent features.
|
||||
* The high-level interfaces of the crypto module is controlled by the parent feature macro,
|
||||
* if there is no parent feature, such interfaces will be unavailable.
|
||||
*/
|
||||
|
||||
#ifndef HITLS_CONFIG_LAYER_H
|
||||
#define HITLS_CONFIG_LAYER_H
|
||||
|
||||
/* BSL_INIT */
|
||||
#if defined(HITLS_CRYPTO_EAL) && !defined(HITLS_BSL_INIT)
|
||||
#define HITLS_BSL_INIT
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_BSL_INIT) && !defined(HITLS_BSL_ERR)
|
||||
#define HITLS_BSL_ERR
|
||||
#endif
|
||||
|
||||
/* BSL_UIO */
|
||||
/* Derive the child-features of uio. */
|
||||
#ifdef HITLS_BSL_UIO
|
||||
#ifndef HITLS_BSL_UIO_PLT
|
||||
#define HITLS_BSL_UIO_PLT
|
||||
#endif
|
||||
#ifndef HITLS_BSL_UIO_BUFFER
|
||||
#define HITLS_BSL_UIO_BUFFER
|
||||
#endif
|
||||
#ifndef HITLS_BSL_UIO_SCTP
|
||||
#define HITLS_BSL_UIO_SCTP
|
||||
#endif
|
||||
#ifndef HITLS_BSL_UIO_TCP
|
||||
#define HITLS_BSL_UIO_TCP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Derive the dependency features of uio_tcp and uio_sctp. */
|
||||
#if defined(HITLS_BSL_UIO_TCP) || defined(HITLS_BSL_UIO_SCTP)
|
||||
#ifndef HITLS_BSL_SAL_NET
|
||||
#define HITLS_BSL_SAL_NET
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Derive parent feature from child features. */
|
||||
#if defined(HITLS_BSL_UIO_BUFFER) || defined(HITLS_BSL_UIO_SCTP) || defined(HITLS_BSL_UIO_TCP)
|
||||
#ifndef HITLS_BSL_UIO_PLT
|
||||
#define HITLS_BSL_UIO_PLT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* KDF */
|
||||
#ifdef HITLS_CRYPTO_KDF
|
||||
#ifndef HITLS_CRYPTO_PBKDF2
|
||||
#define HITLS_CRYPTO_PBKDF2
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_HKDF
|
||||
#define HITLS_CRYPTO_HKDF
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_KDFTLS12
|
||||
#define HITLS_CRYPTO_KDFTLS12
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_SCRYPT
|
||||
#define HITLS_CRYPTO_SCRYPT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_CRYPTO_SCRYPT
|
||||
#ifndef HITLS_CRYPTO_SHA256
|
||||
#define HITLS_CRYPTO_SHA256
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_PBKDF2
|
||||
#define HITLS_CRYPTO_PBKDF2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_PBKDF2) || defined(HITLS_CRYPTO_HKDF) || defined(HITLS_CRYPTO_KDFTLS12) || \
|
||||
defined(HITLS_CRYPTO_SCRYPT)
|
||||
#ifndef HITLS_CRYPTO_KDF
|
||||
#define HITLS_CRYPTO_KDF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_KDF) && !defined(HITLS_CRYPTO_HMAC)
|
||||
#define HITLS_CRYPTO_HMAC
|
||||
#endif
|
||||
|
||||
/* DRBG */
|
||||
#ifdef HITLS_CRYPTO_DRBG
|
||||
#ifndef HITLS_CRYPTO_DRBG_HASH
|
||||
#define HITLS_CRYPTO_DRBG_HASH
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_DRBG_HMAC
|
||||
#define HITLS_CRYPTO_DRBG_HMAC
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_DRBG_CTR
|
||||
#define HITLS_CRYPTO_DRBG_CTR
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_DRBG_HMAC) && !defined(HITLS_CRYPTO_HMAC)
|
||||
#define HITLS_CRYPTO_HMAC
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_DRBG_CTR) && !defined(HITLS_CRYPTO_AES)
|
||||
#define HITLS_CRYPTO_AES
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_DRBG_HASH) || defined(HITLS_CRYPTO_DRBG_HMAC) || defined(HITLS_CRYPTO_DRBG_CTR)
|
||||
#ifndef HITLS_CRYPTO_DRBG
|
||||
#define HITLS_CRYPTO_DRBG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* MAC */
|
||||
#ifdef HITLS_CRYPTO_MAC
|
||||
#ifndef HITLS_CRYPTO_HMAC
|
||||
#define HITLS_CRYPTO_HMAC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_HMAC)
|
||||
#ifndef HITLS_CRYPTO_MAC
|
||||
#define HITLS_CRYPTO_MAC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* CIPHER */
|
||||
#ifdef HITLS_CRYPTO_CIPHER
|
||||
#ifndef HITLS_CRYPTO_AES
|
||||
#define HITLS_CRYPTO_AES
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_SM4
|
||||
#define HITLS_CRYPTO_SM4
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CHACHA20
|
||||
#define HITLS_CRYPTO_CHACHA20
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_CHACHA20) && !defined(HITLS_CRYPTO_CHACHA20POLY1305)
|
||||
#define HITLS_CRYPTO_CHACHA20POLY1305
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_AES) || defined(HITLS_CRYPTO_SM4) || defined(HITLS_CRYPTO_CHACHA20)
|
||||
#ifndef HITLS_CRYPTO_CIPHER
|
||||
#define HITLS_CRYPTO_CIPHER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* MODES */
|
||||
#ifdef HITLS_CRYPTO_MODES
|
||||
#ifndef HITLS_CRYPTO_CTR
|
||||
#define HITLS_CRYPTO_CTR
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CBC
|
||||
#define HITLS_CRYPTO_CBC
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_GCM
|
||||
#define HITLS_CRYPTO_GCM
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CCM
|
||||
#define HITLS_CRYPTO_CCM
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_XTS
|
||||
#define HITLS_CRYPTO_XTS
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CFB
|
||||
#define HITLS_CRYPTO_CFB
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_OFB
|
||||
#define HITLS_CRYPTO_OFB
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CHACHA20POLY1305
|
||||
#define HITLS_CRYPTO_CHACHA20POLY1305
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_CTR) || defined(HITLS_CRYPTO_CBC) || defined(HITLS_CRYPTO_GCM) || \
|
||||
defined(HITLS_CRYPTO_CCM) || defined(HITLS_CRYPTO_XTS) || defined(HITLS_CRYPTO_CFB) || \
|
||||
defined(HITLS_CRYPTO_OFB) || defined(HITLS_CRYPTO_CHACHA20POLY1305)
|
||||
#ifndef HITLS_CRYPTO_MODES
|
||||
#define HITLS_CRYPTO_MODES
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* PKEY */
|
||||
#ifdef HITLS_CRYPTO_PKEY
|
||||
#ifndef HITLS_CRYPTO_ECC
|
||||
#define HITLS_CRYPTO_ECC
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_RSA
|
||||
#define HITLS_CRYPTO_RSA
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_DSA
|
||||
#define HITLS_CRYPTO_DSA
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_DH
|
||||
#define HITLS_CRYPTO_DH
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_ECDSA
|
||||
#define HITLS_CRYPTO_ECDSA
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_ECDH
|
||||
#define HITLS_CRYPTO_ECDH
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_SM2
|
||||
#define HITLS_CRYPTO_SM2
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CURVE25519
|
||||
#define HITLS_CRYPTO_CURVE25519
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_PAILLIER
|
||||
#define HITLS_CRYPTO_PAILLIER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_CRYPTO_ECC
|
||||
#ifndef HITLS_CRYPTO_CURVE_NISTP224
|
||||
#define HITLS_CRYPTO_CURVE_NISTP224
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CURVE_NISTP256
|
||||
#define HITLS_CRYPTO_CURVE_NISTP256
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CURVE_NISTP384
|
||||
#define HITLS_CRYPTO_CURVE_NISTP384
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CURVE_NISTP521
|
||||
#define HITLS_CRYPTO_CURVE_NISTP521
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CURVE_BP256R1
|
||||
#define HITLS_CRYPTO_CURVE_BP256R1
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CURVE_BP384R1
|
||||
#define HITLS_CRYPTO_CURVE_BP384R1
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CURVE_BP512R1
|
||||
#define HITLS_CRYPTO_CURVE_BP512R1
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CURVE_192WAPI
|
||||
#define HITLS_CRYPTO_CURVE_192WAPI
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CURVE_SM2
|
||||
#define HITLS_CRYPTO_CURVE_SM2
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_CURVE_SM9
|
||||
#define HITLS_CRYPTO_CURVE_SM9
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_CURVE_NISTP224) || defined(HITLS_CRYPTO_CURVE_NISTP256) || \
|
||||
defined(HITLS_CRYPTO_CURVE_NISTP384) || defined(HITLS_CRYPTO_CURVE_NISTP521) || \
|
||||
defined(HITLS_CRYPTO_CURVE_BP256R1) || defined(HITLS_CRYPTO_CURVE_BP384R1) || \
|
||||
defined(HITLS_CRYPTO_CURVE_BP512R1) || defined(HITLS_CRYPTO_CURVE_192WAPI) || \
|
||||
defined(HITLS_CRYPTO_CURVE_SM2) || defined(HITLS_CRYPTO_CURVE_SM9)
|
||||
#ifndef HITLS_CRYPTO_ECC
|
||||
#define HITLS_CRYPTO_ECC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_CRYPTO_CURVE25519
|
||||
#ifndef HITLS_CRYPTO_X25519
|
||||
#define HITLS_CRYPTO_X25519
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_ED25519
|
||||
#define HITLS_CRYPTO_ED25519
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_ED25519) && !defined(HITLS_CRYPTO_SHA512)
|
||||
#define HITLS_CRYPTO_SHA512
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_X25519) || defined(HITLS_CRYPTO_ED25519)
|
||||
#ifndef HITLS_CRYPTO_CURVE25519
|
||||
#define HITLS_CRYPTO_CURVE25519
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_CRYPTO_SM2
|
||||
#ifndef HITLS_CRYPTO_SM2_SIGN
|
||||
#define HITLS_CRYPTO_SM2_SIGN
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_SM2_CRYPT
|
||||
#define HITLS_CRYPTO_SM2_CRYPT
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_SM2_EXCH
|
||||
#define HITLS_CRYPTO_SM2_EXCH
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_SM2_SIGN) || defined(HITLS_CRYPTO_SM2_CRYPT) || defined(HITLS_CRYPTO_SM2_EXCH)
|
||||
#ifndef HITLS_CRYPTO_SM2
|
||||
#define HITLS_CRYPTO_SM2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_CRYPTO_SM2
|
||||
#ifndef HITLS_CRYPTO_ENCODE
|
||||
#define HITLS_CRYPTO_ENCODE
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_SM3
|
||||
#define HITLS_CRYPTO_SM3
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_ECC
|
||||
#define HITLS_CRYPTO_ECC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_SM2) && !defined(HITLS_CRYPTO_CURVE_SM2)
|
||||
#define HITLS_CRYPTO_CURVE_SM2
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_ECDH) || defined(HITLS_CRYPTO_ECDSA)
|
||||
#ifndef HITLS_CRYPTO_ECC
|
||||
#define HITLS_CRYPTO_ECC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_SM2)
|
||||
#define HITLS_CRYPTO_CURVE_SM2
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_DSA) || defined(HITLS_CRYPTO_ECDSA)
|
||||
#ifndef HITLS_CRYPTO_ENCODE
|
||||
#define HITLS_CRYPTO_ENCODE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_ECC) || defined(HITLS_CRYPTO_RSA) || defined(HITLS_CRYPTO_DSA)|| defined(HITLS_CRYPTO_DH)
|
||||
#ifndef HITLS_CRYPTO_BN
|
||||
#define HITLS_CRYPTO_BN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_DSA) || defined(HITLS_CRYPTO_CURVE25519) || defined(HITLS_CRYPTO_RSA) || \
|
||||
defined(HITLS_CRYPTO_DH) || defined(HITLS_CRYPTO_ECDSA) || defined(HITLS_CRYPTO_ECDH) || \
|
||||
defined(HITLS_CRYPTO_SM2) || defined(HITLS_CRYPTO_PAILLIER)
|
||||
#ifndef HITLS_CRYPTO_PKEY
|
||||
#define HITLS_CRYPTO_PKEY
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* MD */
|
||||
#ifdef HITLS_CRYPTO_MD
|
||||
#ifndef HITLS_CRYPTO_MD5
|
||||
#define HITLS_CRYPTO_MD5
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_SM3
|
||||
#define HITLS_CRYPTO_SM3
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_SHA1
|
||||
#define HITLS_CRYPTO_SHA1
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_SHA2
|
||||
#define HITLS_CRYPTO_SHA2
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_SHA3
|
||||
#define HITLS_CRYPTO_SHA3
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_CRYPTO_SHA2
|
||||
#ifndef HITLS_CRYPTO_SHA224
|
||||
#define HITLS_CRYPTO_SHA224
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_SHA256
|
||||
#define HITLS_CRYPTO_SHA256
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_SHA384
|
||||
#define HITLS_CRYPTO_SHA384
|
||||
#endif
|
||||
#ifndef HITLS_CRYPTO_SHA512
|
||||
#define HITLS_CRYPTO_SHA512
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_SHA224) && !defined(HITLS_CRYPTO_SHA256)
|
||||
#define HITLS_CRYPTO_SHA256
|
||||
#endif
|
||||
#if defined(HITLS_CRYPTO_SHA384) && !defined(HITLS_CRYPTO_SHA512)
|
||||
#define HITLS_CRYPTO_SHA512
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_SHA256) || defined(HITLS_CRYPTO_SHA512)
|
||||
#ifndef HITLS_CRYPTO_SHA2
|
||||
#define HITLS_CRYPTO_SHA2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_MD5) || defined(HITLS_CRYPTO_SM3) || defined(HITLS_CRYPTO_SHA1) || \
|
||||
defined(HITLS_CRYPTO_SHA2) || defined(HITLS_CRYPTO_SHA3)
|
||||
#ifndef HITLS_CRYPTO_MD
|
||||
#define HITLS_CRYPTO_MD
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_MODES_X8664)
|
||||
#define HITLS_CRYPTO_CHACHA20POLY1305_X8664
|
||||
#define HITLS_CRYPTO_GCM_X8664
|
||||
#endif
|
||||
|
||||
#if defined(HITLS_CRYPTO_MODES_ARMV8)
|
||||
#define HITLS_CRYPTO_CHACHA20POLY1305_ARMV8
|
||||
#define HITLS_CRYPTO_GCM_ARMV8
|
||||
#endif
|
||||
|
||||
#if (defined(HITLS_CRYPTO_MODES_X8664) || defined(HITLS_CRYPTO_MODES_ARMV7) || defined(HITLS_CRYPTO_MODES_ARMV8)) && \
|
||||
!defined(HITLS_CRYPTO_MODES_ASM)
|
||||
#define HITLS_CRYPTO_MODES_ASM
|
||||
#endif
|
||||
|
||||
#endif /* HITLS_CONFIG_LAYER_H */
|
||||
+518
@@ -0,0 +1,518 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# This file is part of the openHiTLS project.
|
||||
#
|
||||
# openHiTLS is licensed under the Mulan PSL v2.
|
||||
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
# You may obtain a copy of Mulan PSL v2 at:
|
||||
#
|
||||
# http://license.coscl.org.cn/MulanPSL2
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
# See the Mulan PSL v2 for more details.
|
||||
"""
|
||||
Customize the openHiTLS build.
|
||||
Generate the modules.cmake file based on command line arguments and configuration files.
|
||||
|
||||
Options usage and examples:
|
||||
1 Enable the feature on demand and specify the implementation type of the feature, c or assembly.
|
||||
# Use 'enable' to specify the features to be constructed.
|
||||
# Compile C code if there is no other parameter.
|
||||
./configure.py --enable all # Build all features of openHiTLS.
|
||||
./configure.py --enable hitls_crypto # Build all features in the lib hitls_crypto.
|
||||
./configure.py --enable md # Build all sub features of md.
|
||||
./configure.py --enable sha2 sha3 hmac # Specifies to build certain features.
|
||||
|
||||
# Use 'enable' to specify the features to be constructed.
|
||||
# Use 'asm_type' to specify the assembly type.
|
||||
# If there are features in enable list that supports assembly, compile its assembly implementation.
|
||||
./configure.py --enable sm3 aes ... --asm_type armv8
|
||||
|
||||
# Use 'enable' to specify the features to be constructed.
|
||||
# Use 'asm_type' to specify the assembly type.
|
||||
# Use 'asm' to specify the assembly feature(s), which is(are) based on the enabled features.
|
||||
# Compile the assembly code of the features in the asm, and the C code of other features in the enable list.
|
||||
./configure.py --enable sm3 aes ... --asm_type armv8 --asm sm3
|
||||
|
||||
2 Compile options: Add or delete compilation options based on the default compilation options (compile.json).
|
||||
./configure.py --add_options "-O0 -g" --del_options "-O2 -D_FORTIFY_SOURCE=2"
|
||||
|
||||
3 Link options: Add or delete link options based on the default link options (compile.json).
|
||||
./configure.py --add_link_flags "xxx xxx" --del_link_flags "xxx xxx"
|
||||
|
||||
4 Set the endian mode of the system. Set the endian mode of the system. The default value is little endian.
|
||||
./configure.py --endian big
|
||||
|
||||
5 Specifies the system type.
|
||||
./configure.py --system linux
|
||||
|
||||
6 Specifies the number of system bits.
|
||||
./configure.py --bits 32
|
||||
|
||||
7 Generating modules.cmake
|
||||
./configure.py -m
|
||||
|
||||
8 Specifies the directory where the compilation middleware is generated. The default directory is ./output.
|
||||
./configure.py --build_dir build
|
||||
|
||||
9 Specifies the lib type.
|
||||
./configure.py --lib_type static
|
||||
./configure.py --lib_type static shared object
|
||||
|
||||
10 You can directly specify the compilation configuration files, omitting the above 1~9 command line parameters.
|
||||
For the file format, please refer to the compile_config.json and feature_config.json files generated after executing
|
||||
the above 1~9 commands.
|
||||
./configure.py --feature_config path/to/xxx.json --compile_config path/to/xxx.json
|
||||
|
||||
Note:
|
||||
Options for different functions can be combined.
|
||||
"""
|
||||
|
||||
import sys
|
||||
sys.dont_write_bytecode = True
|
||||
import os
|
||||
import argparse
|
||||
import traceback
|
||||
import glob
|
||||
from script.methods import copy_file, save_json_file, trans2list
|
||||
from script.config_parser import (FeatureParser, CompileParser, FeatureConfigParser,
|
||||
CompileConfigParser, CompleteOptionParser)
|
||||
|
||||
srcdir = os.path.dirname(os.path.realpath(sys.argv[0]))
|
||||
work_dir = os.path.abspath(os.getcwd())
|
||||
|
||||
def get_cfg_args():
|
||||
parser = argparse.ArgumentParser(prog='openHiTLS', description='parser configure arguments')
|
||||
try:
|
||||
# Version/Release Build Configuration Parameters
|
||||
parser.add_argument('-m', '--module_cmake', action='store_true', help='generate moudules.cmake file')
|
||||
parser.add_argument('--build_dir', metavar='dir', type=str, default=os.path.join(srcdir, 'build'),
|
||||
help='compile temp directory')
|
||||
parser.add_argument('--output_dir', metavar='dir', type=str, default=os.path.join(srcdir, 'output'),
|
||||
help='compile output directory')
|
||||
# Configuration file
|
||||
parser.add_argument('--feature_config', metavar='file_path', type=str, default='',
|
||||
help='Configuration file of the compilation features.')
|
||||
parser.add_argument('--compile_config', metavar='file_path', type=str, default='',
|
||||
help='Configuration file of compilation parameters.')
|
||||
# Compilation Feature Configuration
|
||||
parser.add_argument('--enable', metavar='feature', nargs='+', default=[],
|
||||
help='enable some libs or features, such as --enable sha256 aes gcm_asm, default is "all"')
|
||||
parser.add_argument('--disable', action='extend', metavar='feature', nargs='+', default=['uio_sctp'],
|
||||
help='disable some libs or features, such as --disable aes gcm_asm, default is disable "uio_sctp" ')
|
||||
parser.add_argument('--enable-sctp', action="store_true", help='enable sctp which is used in DTLS')
|
||||
parser.add_argument('--asm_type', type=str, help='Assembly Type, default is "no_asm".')
|
||||
parser.add_argument('--asm', metavar='feature', default=[], nargs='+', help='config asm, such as --asm sha2')
|
||||
# System Configuration
|
||||
parser.add_argument('--system', metavar='linux', type=str, choices=['linux'],
|
||||
help='To enable feature "sal_xxx", should specify the system, default is "linux".')
|
||||
parser.add_argument('--endian', metavar='little|big', type=str, choices=['little', 'big'],
|
||||
help='Specify the platform endianness as little or big, default is "little".')
|
||||
parser.add_argument('--bits', metavar='32|64', type=int, choices=[32, 64],
|
||||
help='To enable feature "bn", should specify the number of OS bits, default is "64".')
|
||||
# Compiler Options, Link Options
|
||||
parser.add_argument('--lib_type', choices=['static', 'shared', 'object'], nargs='+',
|
||||
help='set lib type, such as --lib_type staic shared, default is "staic shared object"')
|
||||
parser.add_argument('--add_options', default='', type=str,
|
||||
help='add some compile options, such as --add_options="-O0 -g"')
|
||||
parser.add_argument('--del_options', default='', type=str,
|
||||
help='delete some compile options such as --del_options="-O2 -Werror"')
|
||||
parser.add_argument('--add_link_flags', default='', type=str,
|
||||
help='add some link flags such as --add_link_flags="-pie"')
|
||||
parser.add_argument('--del_link_flags', default='', type=str,
|
||||
help='delete some link flags such as --del_link_flags="-shared -Wl,-z,relro"')
|
||||
|
||||
parser.add_argument('--hitls_version', default='openHiTLS 0.1.0 25 12 2023', help='%(prog)s version str')
|
||||
parser.add_argument('--hitls_version_num', default=0x00001000, help='%(prog)s version num')
|
||||
|
||||
args = vars(parser.parse_args())
|
||||
|
||||
args['tmp_feature_config'] = os.path.join(args['build_dir'], 'feature_config.json')
|
||||
args['tmp_compile_config'] = os.path.join(args['build_dir'], 'compile_config.json')
|
||||
|
||||
# disable uio_sctp by default
|
||||
if args['enable_sctp'] or args['module_cmake']:
|
||||
args['disable'].remove('uio_sctp')
|
||||
|
||||
except argparse.ArgumentError as e:
|
||||
parser.print_help()
|
||||
raise ValueError("Error: Failed to obtain parameters.") from e
|
||||
|
||||
return argparse.Namespace(**args)
|
||||
|
||||
class Configure:
|
||||
"""Provides operations related to configuration and input parameter parsing:
|
||||
1 Parse input parameters.
|
||||
2 Read configuration files and input parameters.
|
||||
3 Update the final configuration files in the build directory.
|
||||
"""
|
||||
config_json_file = 'config.json'
|
||||
feature_json_file = 'config/json/feature.json'
|
||||
complete_options_json_file = 'config/json/complete_options.json'
|
||||
default_compile_json_file = 'config/json/compile.json'
|
||||
|
||||
def __init__(self, features: FeatureParser):
|
||||
self._features = features
|
||||
self._args = get_cfg_args()
|
||||
self._preprocess_args()
|
||||
|
||||
@property
|
||||
def args(self):
|
||||
return self._args
|
||||
|
||||
def _preprocess_args(self):
|
||||
if self._args.feature_config and not os.path.exists(self._args.feature_config):
|
||||
raise FileNotFoundError('File not found: %s' % self._args.feature_config)
|
||||
if self._args.compile_config and not os.path.exists(self._args.compile_config):
|
||||
raise FileNotFoundError('File not found: %s' % self._args.compile_config)
|
||||
|
||||
if 'all' in self._args.enable:
|
||||
if len(self._args.enable) > 1:
|
||||
raise ValueError("Error: 'all' and other features cannot be set at the same time.")
|
||||
else:
|
||||
for fea in self._args.enable:
|
||||
if fea in self._features.libs or fea in self._features.feas_info:
|
||||
continue
|
||||
raise ValueError("unrecognized fea '%s'" % fea)
|
||||
|
||||
if self._args.asm_type:
|
||||
if self._args.asm_type not in self._features.asm_types:
|
||||
raise ValueError("Unsupported asm_type: asm_type should be one of [%s]" % self._features.asm_types)
|
||||
else:
|
||||
if self._args.asm and not self._args.asm_type:
|
||||
raise ValueError("Error: 'asm_type' and 'asm' must be set at the same time.")
|
||||
# The value of 'asm' will be verified later.
|
||||
|
||||
@staticmethod
|
||||
def _load_config(is_fea_cfg, src_file, dest_file):
|
||||
if os.path.exists(dest_file):
|
||||
if src_file != '':
|
||||
raise FileExistsError('{} already exists'.format(dest_file))
|
||||
else:
|
||||
if src_file == '':
|
||||
# No custom configuration file is specified, create a default config file.
|
||||
cfg = FeatureConfigParser.default_cfg() if is_fea_cfg else CompileConfigParser.default_cfg()
|
||||
save_json_file(cfg, dest_file)
|
||||
else:
|
||||
copy_file(src_file, dest_file)
|
||||
|
||||
def load_config_to_build(self):
|
||||
"""Load the compilation feature and compilation option configuration files to the build directory:
|
||||
build/feature_config.json
|
||||
build/compile_config.json
|
||||
"""
|
||||
if not os.path.exists(self._args.build_dir):
|
||||
os.makedirs(self._args.build_dir)
|
||||
self._load_config(True, self._args.feature_config, self._args.tmp_feature_config)
|
||||
self._load_config(False, self._args.compile_config, self._args.tmp_compile_config)
|
||||
|
||||
def update_feature_config(self):
|
||||
"""Update the feature configuration file in the build based on the input parameters."""
|
||||
conf_custom_feature = FeatureConfigParser(self._features, self._args.tmp_feature_config)
|
||||
|
||||
# 'enable' default is 'all'
|
||||
if not conf_custom_feature.libs and not self._args.enable:
|
||||
self._args.enable = ['all']
|
||||
|
||||
# Set parameters by referring to "FeatureConfigParser.key_value".
|
||||
conf_custom_feature.set_param('libType', self._args.lib_type)
|
||||
conf_custom_feature.set_param('endian', self._args.endian)
|
||||
conf_custom_feature.set_param('system', self._args.system, False)
|
||||
conf_custom_feature.set_param('bits', self._args.bits, False)
|
||||
|
||||
enable_feas, added_asm_feas = conf_custom_feature.get_enable_feas(self._args.enable)
|
||||
|
||||
if self._args.asm_type:
|
||||
conf_custom_feature.set_asm_type(self._args.asm_type)
|
||||
conf_custom_feature.set_asm_features(enable_feas, added_asm_feas, self._args.asm_type, self._args.asm)
|
||||
|
||||
conf_custom_feature.set_c_features(enable_feas)
|
||||
|
||||
# update feature and resave file.
|
||||
conf_custom_feature.update_feature(self._args.enable, self._args.disable)
|
||||
conf_custom_feature.save(self._args.tmp_feature_config)
|
||||
|
||||
def update_compile_config(self, all_options: CompleteOptionParser):
|
||||
"""Update the compilation configuration file in the build based on the input parameters."""
|
||||
conf_custom_compile = CompileConfigParser(all_options, self._args.tmp_compile_config)
|
||||
|
||||
if self._args.add_options:
|
||||
conf_custom_compile.change_options(self._args.add_options.strip().split(' '), True)
|
||||
if self._args.del_options:
|
||||
conf_custom_compile.change_options(self._args.del_options.strip().split(' '), False)
|
||||
|
||||
if self._args.add_link_flags:
|
||||
conf_custom_compile.change_link_flags(self._args.add_link_flags.strip().split(' '), True)
|
||||
if self._args.del_link_flags:
|
||||
conf_custom_compile.change_link_flags(self._args.del_link_flags.strip().split(' '), False)
|
||||
|
||||
conf_custom_compile.save(self._args.tmp_compile_config)
|
||||
|
||||
class CMakeGenerator:
|
||||
""" Generating CMake Commands and Scripts Based on Configuration Files """
|
||||
def __init__(self, args, features: FeatureParser, all_options: CompleteOptionParser):
|
||||
self._args = args
|
||||
self._cfg_feature = features
|
||||
self._cfg_compile = CompileParser(all_options, Configure.default_compile_json_file)
|
||||
self._cfg_custom_feature = FeatureConfigParser(features, args.tmp_feature_config)
|
||||
self._cfg_custom_feature.check_fea_opts()
|
||||
self._cfg_custom_compile = CompileConfigParser(all_options, args.tmp_compile_config)
|
||||
|
||||
self._asm_type = self._cfg_custom_feature.asm_type
|
||||
|
||||
self._platform = 'linux'
|
||||
|
||||
@staticmethod
|
||||
def _get_lib_common_include(modules: list):
|
||||
""" modules: ['::','::']"""
|
||||
inc_dirs = set()
|
||||
top_modules = set(x.split('::')[0] for x in modules)
|
||||
top_modules.add('bsl/log')
|
||||
top_modules.add('bsl/err')
|
||||
for module in top_modules:
|
||||
path = module + '/include'
|
||||
if os.path.exists(path):
|
||||
inc_dirs.add(path)
|
||||
path = 'include/' + module
|
||||
if os.path.exists(path):
|
||||
inc_dirs.add(path)
|
||||
if os.path.exists('config/macro_config'):
|
||||
inc_dirs.add('config/macro_config')
|
||||
if os.path.exists('../../../../Secure_C/include'):
|
||||
inc_dirs.add('../../../../Secure_C/include')
|
||||
if os.path.exists('../../../platform/Secure_C/include'):
|
||||
inc_dirs.add('../../../platform/Secure_C/include')
|
||||
return inc_dirs
|
||||
|
||||
def _get_module_include(self, mod: str, dep_mods: list):
|
||||
inc_dirs = set()
|
||||
dep_mods.append(mod)
|
||||
for dep in dep_mods:
|
||||
top_dir, sub_dir = dep.split('::')
|
||||
path = "{}/{}/include".format(top_dir, sub_dir)
|
||||
if os.path.exists(path):
|
||||
inc_dirs.add(path)
|
||||
top_mod, sub_mod = dep.split('::')
|
||||
|
||||
cfg_inc = self._cfg_feature.modules[top_mod][sub_mod].get('.include', [])
|
||||
for inc_dir in cfg_inc:
|
||||
if os.path.exists(inc_dir):
|
||||
inc_dirs.add(inc_dir)
|
||||
return inc_dirs
|
||||
|
||||
@staticmethod
|
||||
def _expand_srcs(srcs):
|
||||
if not srcs:
|
||||
return []
|
||||
|
||||
ret = []
|
||||
for x in srcs:
|
||||
ret += glob.glob(x, recursive=True)
|
||||
if len(ret) == 0:
|
||||
raise SystemError("The .c file does not exist in the {} directory.".format(srcs))
|
||||
ret.sort()
|
||||
return ret
|
||||
|
||||
@classmethod
|
||||
def _gen_cmd_cmake(cls, cmd: str, title, content_obj=None):
|
||||
if not content_obj:
|
||||
return '{}({})\n'.format(cmd, title)
|
||||
|
||||
items = None
|
||||
if isinstance(content_obj, list) or isinstance(content_obj, set):
|
||||
items = content_obj
|
||||
elif isinstance(content_obj, dict):
|
||||
items = content_obj.values()
|
||||
elif isinstance(content_obj, str):
|
||||
items = [content_obj]
|
||||
else:
|
||||
raise ValueError('Unsupported type "%s"' % type(content_obj))
|
||||
|
||||
content = ''
|
||||
for item in items:
|
||||
content += ' {}\n'.format(item)
|
||||
|
||||
if len(items) == 1:
|
||||
return '{}({} {})\n'.format(cmd, title, item)
|
||||
else:
|
||||
return '{}({}\n{})\n'.format(cmd, title, content)
|
||||
|
||||
def _get_module_src_set(self, lib, top_mod, sub_mod, mod_obj):
|
||||
srcs = self._cfg_feature.get_mod_srcs(top_mod, sub_mod, mod_obj)
|
||||
return self._expand_srcs(srcs)
|
||||
|
||||
def _gen_module_cmake(self, lib, mod, mod_obj, mods_cmake):
|
||||
top_mod, module_name = mod.split('::')
|
||||
inc_set = self._get_module_include(mod, mod_obj.get('deps', []))
|
||||
src_list = self._get_module_src_set(lib, top_mod, module_name, mod_obj)
|
||||
|
||||
tgt_name = module_name + '-objs'
|
||||
cmake = '\n# Add module {} \n'.format(module_name)
|
||||
cmake += self._gen_cmd_cmake('add_library', '{} OBJECT'.format(tgt_name))
|
||||
cmake += self._gen_cmd_cmake('target_include_directories', '{} PRIVATE'.format(tgt_name), inc_set)
|
||||
cmake += self._gen_cmd_cmake('target_sources', '{} PRIVATE'.format(tgt_name), src_list)
|
||||
mods_cmake[tgt_name] = cmake
|
||||
|
||||
def _gen_shared_lib_cmake(self, lib_name, tgt_obj_list, tgt_list, macros):
|
||||
tgt_name = lib_name + '-shared'
|
||||
properties = 'OUTPUT_NAME {}'.format(lib_name)
|
||||
|
||||
cmake = '\n'
|
||||
cmake += self._gen_cmd_cmake('add_library', '{} SHARED'.format(tgt_name), tgt_obj_list)
|
||||
cmake += self._gen_cmd_cmake('target_link_options', '{} PRIVATE'.format(tgt_name), '${SHARED_LNK_FLAGS}')
|
||||
cmake += self._gen_cmd_cmake('set_target_properties', '{} PROPERTIES'.format(tgt_name), properties)
|
||||
cmake += 'install(TARGETS %s DESTINATION ${CMAKE_INSTALL_PREFIX})\n' % tgt_name
|
||||
|
||||
if lib_name == 'hitls_bsl':
|
||||
for item in macros:
|
||||
if item == '-DHITLS_BSL_UIO' or item == '-DHITLS_BSL_UIO_SCTP':
|
||||
cmake += self._gen_cmd_cmake("target_link_libraries", "hitls_bsl-shared sctp")
|
||||
if lib_name == 'hitls_crypto':
|
||||
cmake += self._gen_cmd_cmake("target_link_libraries", "hitls_crypto-shared hitls_bsl-shared")
|
||||
if lib_name == 'hitls_tls':
|
||||
cmake += self._gen_cmd_cmake("target_link_libraries", "hitls_tls-shared hitls_bsl-shared")
|
||||
tgt_list.append(tgt_name)
|
||||
return cmake
|
||||
|
||||
def _gen_static_lib_cmake(self, lib_name, tgt_obj_list, tgt_list):
|
||||
tgt_name = lib_name + '-static'
|
||||
properties = 'OUTPUT_NAME {}'.format(lib_name)
|
||||
|
||||
cmake = '\n'
|
||||
cmake += self._gen_cmd_cmake('add_library', '{} STATIC'.format(tgt_name), tgt_obj_list)
|
||||
cmake += self._gen_cmd_cmake('set_target_properties', '{} PROPERTIES'.format(tgt_name), properties)
|
||||
cmake += 'install(TARGETS %s DESTINATION ${CMAKE_INSTALL_PREFIX})\n' % tgt_name
|
||||
|
||||
tgt_list.append(tgt_name)
|
||||
return cmake
|
||||
|
||||
def _gen_obejct_lib_cmake(self, lib_name, tgt_obj_list, tgt_list):
|
||||
tgt_name = lib_name + '-object'
|
||||
properties = 'OUTPUT_NAME lib{}.o'.format(lib_name)
|
||||
|
||||
cmake = '\n'
|
||||
cmake += self._gen_cmd_cmake('add_executable', tgt_name, tgt_obj_list)
|
||||
cmake += self._gen_cmd_cmake('target_link_options', '{} PRIVATE'.format(tgt_name), '${PIE_EXE_LNK_FLAGS}')
|
||||
cmake += self._gen_cmd_cmake('set_target_properties', '{} PROPERTIES'.format(tgt_name), properties)
|
||||
cmake += 'install(TARGETS %s DESTINATION ${CMAKE_INSTALL_PREFIX})\n' % tgt_name
|
||||
|
||||
tgt_list.append(tgt_name)
|
||||
return cmake
|
||||
|
||||
def _gen_lib_cmake(self, lib_name, inc_dirs, lib_obj, macros):
|
||||
lang = self._cfg_feature.libs[lib_name].get('lang', 'C')
|
||||
definitions = '"${CMAKE_C_FLAGS} -DOPENHITLS_VERSION_S=\'\\"%s\\"\' -DOPENHITLS_VERSION_I=%lu %s"' % (
|
||||
self._args.hitls_version, self._args.hitls_version_num, '-D__FILENAME__=\'\\"$(notdir $(subst .o,,$@))\\"\'')
|
||||
|
||||
cmake = 'project({} {})\n\n'.format(lib_name, lang)
|
||||
cmake += self._gen_cmd_cmake('set', 'CMAKE_ASM_NASM_OBJECT_FORMAT elf64')
|
||||
cmake += self._gen_cmd_cmake('set', 'CMAKE_C_FLAGS', '${CC_ALL_OPTIONS}')
|
||||
cmake += self._gen_cmd_cmake('set', 'CMAKE_ASM_FLAGS', '${CC_ALL_OPTIONS}')
|
||||
cmake += self._gen_cmd_cmake('set', 'CMAKE_C_FLAGS', definitions)
|
||||
cmake += self._gen_cmd_cmake('include_directories', '', inc_dirs)
|
||||
for _, mod_cmake in lib_obj['mods_cmake'].items():
|
||||
cmake += mod_cmake
|
||||
|
||||
tgt_obj_list = list('$<TARGET_OBJECTS:{}>'.format(x) for x in lib_obj['mods_cmake'].keys())
|
||||
|
||||
tgt_list = []
|
||||
lib_type = self._cfg_custom_feature.lib_type
|
||||
if 'shared' in lib_type:
|
||||
cmake += self._gen_shared_lib_cmake(lib_name, tgt_obj_list, tgt_list, macros)
|
||||
if 'static' in lib_type:
|
||||
cmake += self._gen_static_lib_cmake(lib_name, tgt_obj_list, tgt_list)
|
||||
if 'object' in lib_type:
|
||||
cmake += self._gen_obejct_lib_cmake(lib_name, tgt_obj_list, tgt_list)
|
||||
lib_obj['cmake'] = cmake
|
||||
lib_obj['targets'] = tgt_list
|
||||
|
||||
def _gen_projects_cmake(self, macros):
|
||||
lib_enable_modules = self._cfg_custom_feature.get_enable_modules()
|
||||
|
||||
projects = {}
|
||||
for lib, lib_obj in lib_enable_modules.items():
|
||||
projects[lib] = {}
|
||||
projects[lib]['mods_cmake'] = {}
|
||||
inc_dirs = self._get_lib_common_include(lib_obj.keys())
|
||||
for mod, mod_obj in lib_obj.items():
|
||||
self._gen_module_cmake(lib, mod, mod_obj, projects[lib]['mods_cmake'])
|
||||
self._gen_lib_cmake(lib, inc_dirs, projects[lib], macros)
|
||||
|
||||
return projects
|
||||
|
||||
def _gen_target_cmake(self, projects, lib_tgts):
|
||||
cmake = 'add_custom_target(openHiTLS)\n'
|
||||
cmake += self._gen_cmd_cmake('add_dependencies', 'openHiTLS', lib_tgts)
|
||||
return cmake
|
||||
|
||||
def _gen_set_param_cmake(self, macro_file):
|
||||
compile_flags, link_flags = self._cfg_compile.union_options(self._cfg_custom_compile)
|
||||
macros = self._cfg_custom_feature.get_fea_macros()
|
||||
macros.sort()
|
||||
compile_flags.extend(macros)
|
||||
hitls_macros = list(filter(lambda x: '-DHITLS' in x, compile_flags))
|
||||
with open(macro_file, "w") as f:
|
||||
f.write(" ".join(hitls_macros))
|
||||
f.close()
|
||||
|
||||
compile_flags_str = '"{}"'.format(" ".join(compile_flags))
|
||||
shared_link_flags = '{}'.format(" ".join(link_flags['SHARED']) + " " + " ".join(link_flags['PUBLIC']))
|
||||
exe_link_flags = '{}'.format(" ".join(link_flags['EXE']) + " " + " ".join(link_flags['PUBLIC']))
|
||||
|
||||
cmake = self._gen_cmd_cmake('set', 'CC_ALL_OPTIONS', compile_flags_str) + "\n"
|
||||
cmake += self._gen_cmd_cmake('set', 'SHARED_LNK_FLAGS', shared_link_flags) + "\n"
|
||||
cmake += self._gen_cmd_cmake('set', 'PIE_EXE_LNK_FLAGS', exe_link_flags) + "\n"
|
||||
|
||||
return cmake, macros
|
||||
|
||||
def out_cmake(self, cmake_path, macro_file):
|
||||
self._cfg_custom_feature._check_bn_config()
|
||||
self._cfg_custom_feature._check_system_config()
|
||||
|
||||
set_param_cmake, macros = self._gen_set_param_cmake(macro_file)
|
||||
|
||||
projects = self._gen_projects_cmake(macros)
|
||||
|
||||
lib_tgts = list(tgt for lib_obj in projects.values() for tgt in lib_obj['targets'])
|
||||
botom_cmake = self._gen_target_cmake(projects, lib_tgts)
|
||||
|
||||
with open(cmake_path, "w") as f:
|
||||
f.write(set_param_cmake)
|
||||
for lib_obj in projects.values():
|
||||
f.write(lib_obj['cmake'])
|
||||
f.write('\n\n')
|
||||
f.write(botom_cmake)
|
||||
|
||||
def main():
|
||||
os.chdir(srcdir)
|
||||
|
||||
# The Python version cannot be earlier than 3.5.
|
||||
if sys.version_info < (3, 5):
|
||||
print("your python version %d.%d should not be lower than 3.5" % tuple(sys.version_info[:2]))
|
||||
raise Exception("your python version %d.%d should not be lower than 3.5" % tuple(sys.version_info[:2]))
|
||||
|
||||
conf_feature = FeatureParser(Configure.feature_json_file)
|
||||
complete_options = CompleteOptionParser(Configure.complete_options_json_file)
|
||||
|
||||
cfg = Configure(conf_feature)
|
||||
cfg.load_config_to_build()
|
||||
cfg.update_feature_config()
|
||||
cfg.update_compile_config(complete_options)
|
||||
|
||||
if cfg.args.module_cmake:
|
||||
tmp_cmake = os.path.join(cfg.args.build_dir, 'modules.cmake')
|
||||
macro_file = os.path.join(cfg.args.build_dir, 'macro.txt')
|
||||
if (os.path.exists(macro_file)):
|
||||
os.remove(macro_file)
|
||||
CMakeGenerator(cfg.args, conf_feature, complete_options).out_cmake(tmp_cmake, macro_file)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except SystemExit:
|
||||
exit(0)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
exit(2)
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef CRYPT_AES_H
|
||||
#define CRYPT_AES_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_CRYPTO_AES
|
||||
|
||||
#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 key structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t key[CRYPT_AES_MAX_KEYLEN];
|
||||
uint32_t rounds;
|
||||
} CRYPT_AES_Key;
|
||||
|
||||
/**
|
||||
* @ingroup aes
|
||||
* @brief Set the AES encryption key.
|
||||
*
|
||||
* @param ctx [IN] AES handle
|
||||
* @param key [IN] Encryption key
|
||||
* @param len [IN] Key length. The value must be 16 bytes.
|
||||
*/
|
||||
int32_t CRYPT_AES_SetEncryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len);
|
||||
|
||||
/**
|
||||
* @ingroup aes
|
||||
* @brief Set the AES encryption key.
|
||||
*
|
||||
* @param ctx [IN] AES handle
|
||||
* @param key [IN] Encryption key
|
||||
* @param len [IN] Key length. The value must be 24 bytes.
|
||||
*/
|
||||
int32_t CRYPT_AES_SetEncryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len);
|
||||
|
||||
/**
|
||||
* @ingroup aes
|
||||
* @brief Set the AES encryption key.
|
||||
*
|
||||
* @param ctx [IN] AES handle
|
||||
* @param key [IN] Encryption key
|
||||
* @param len [IN] Key length. The value must be 32 bytes.
|
||||
*/
|
||||
int32_t CRYPT_AES_SetEncryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len);
|
||||
|
||||
/**
|
||||
* @ingroup aes
|
||||
* @brief Set the AES decryption key.
|
||||
*
|
||||
* @param ctx [IN] AES handle
|
||||
* @param key [IN] Decryption key
|
||||
* @param len [IN] Key length. The value must be 16 bytes.
|
||||
*/
|
||||
int32_t CRYPT_AES_SetDecryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len);
|
||||
|
||||
/**
|
||||
* @ingroup aes
|
||||
* @brief Set the AES decryption key.
|
||||
*
|
||||
* @param ctx [IN] AES handle
|
||||
* @param key [IN] Decryption key
|
||||
* @param len [IN] Key length. The value must be 24 bytes.
|
||||
*/
|
||||
int32_t CRYPT_AES_SetDecryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len);
|
||||
|
||||
/**
|
||||
* @ingroup aes
|
||||
* @brief Set the AES decryption key.
|
||||
*
|
||||
* @param ctx [IN] AES handle
|
||||
* @param key [IN] Decryption key
|
||||
* @param len [IN] Key length. The value must be 32 bytes.
|
||||
*/
|
||||
int32_t CRYPT_AES_SetDecryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len);
|
||||
|
||||
/**
|
||||
* @ingroup aes
|
||||
* @brief AES encryption
|
||||
*
|
||||
* @param ctx [IN] AES handle, storing keys
|
||||
* @param in [IN] Input plaintext data. The value must be 16 bytes.
|
||||
* @param out [OUT] Output ciphertext data. The length is 16 bytes.
|
||||
* @param len [IN] Block length.
|
||||
*/
|
||||
int32_t CRYPT_AES_Encrypt(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
|
||||
|
||||
/**
|
||||
* @ingroup aes
|
||||
* @brief AES decryption
|
||||
*
|
||||
* @param ctx [IN] AES handle, storing keys
|
||||
* @param in [IN] Input ciphertext data. The value must be 16 bytes.
|
||||
* @param out [OUT] Output plaintext data. The length is 16 bytes.
|
||||
* @param len [IN] Block length. The length is 16.
|
||||
*/
|
||||
int32_t CRYPT_AES_Decrypt(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
|
||||
|
||||
#ifdef HITLS_CRYPTO_CBC
|
||||
/**
|
||||
* @ingroup aes
|
||||
* @brief AES cbc encryption
|
||||
*
|
||||
* @param ctx [IN] AES handle, storing keys
|
||||
* @param in [IN] Input plaintext data, 16 bytes.
|
||||
* @param out [OUT] Output ciphertext data. The length is 16 bytes.
|
||||
* @param len [IN] Block length.
|
||||
* @param iv [IN] Initialization vector.
|
||||
*/
|
||||
int32_t CRYPT_AES_CBC_Encrypt(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv);
|
||||
|
||||
/**
|
||||
* @ingroup aes
|
||||
* @brief AES cbc decryption
|
||||
*
|
||||
* @param ctx [IN] AES handle, storing keys
|
||||
* @param in [IN] Input ciphertext data. The value is 16 bytes.
|
||||
* @param out [OUT] Output plaintext data. The length is 16 bytes.
|
||||
* @param len [IN] Block length.
|
||||
* @param iv [IN] Initialization vector.
|
||||
*/
|
||||
int32_t CRYPT_AES_CBC_Decrypt(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv);
|
||||
#endif /* HITLS_CRYPTO_CBC */
|
||||
|
||||
#if defined(HITLS_CRYPTO_CTR) || defined(HITLS_CRYPTO_GCM)
|
||||
/**
|
||||
* @ingroup aes
|
||||
* @brief AES ctr encryption
|
||||
*
|
||||
* @param ctx [IN] AES handle, storing keys
|
||||
* @param in [IN] Input plaintext data, 16 bytes.
|
||||
* @param out [OUT] Output ciphertext data. The length is 16 bytes.
|
||||
* @param len [IN] Block length.
|
||||
* @param iv [IN] Initialization vector.
|
||||
*/
|
||||
int32_t CRYPT_AES_CTR_Encrypt(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv);
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_CRYPTO_ECB
|
||||
/**
|
||||
* @ingroup aes
|
||||
* @brief AES ecb encryption
|
||||
*
|
||||
* @param ctx [IN] AES handle, storing keys
|
||||
* @param in [IN] Input plaintext data. The length is a multiple of 16 bytes.
|
||||
* @param out [OUT] Output ciphertext data. The length is a multiple of 16 bytes.
|
||||
* @param len [IN] Block length.
|
||||
*/
|
||||
int32_t CRYPT_AES_ECB_Encrypt(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
|
||||
|
||||
/**
|
||||
* @ingroup aes
|
||||
* @brief AES ecb decryption
|
||||
*
|
||||
* @param ctx [IN] AES handle, storing keys
|
||||
* @param in [IN] Input ciphertext data. The value is 16 bytes.
|
||||
* @param out [OUT] Output plaintext data. The length is 16 bytes.
|
||||
* @param len [IN] Block length.
|
||||
*/
|
||||
int32_t CRYPT_AES_ECB_Decrypt(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
|
||||
#endif
|
||||
|
||||
#ifdef HITLS_CRYPTO_CFB
|
||||
/**
|
||||
* @brief Decryption in CFB mode
|
||||
*
|
||||
* @param ctx [IN] Mode handle
|
||||
* @param in [IN] Data to be encrypted
|
||||
* @param out [OUT] Encrypted data
|
||||
* @param len [IN] Data length
|
||||
* @param iv [IN] Initial vector
|
||||
* @return Success response: CRYPT_SUCCESS
|
||||
* Returned upon failure: Other error codes.
|
||||
*/
|
||||
int32_t CRYPT_AES_CFB_Decrypt(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup aes
|
||||
* @brief Delete the AES key information.
|
||||
*
|
||||
* @param ctx [IN] AES handle, storing keys
|
||||
* @return void
|
||||
*/
|
||||
void CRYPT_AES_Clean(CRYPT_AES_Key *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // HITLS_CRYPTO_AES
|
||||
|
||||
#endif // CRYPT_AES_H
|
||||
@@ -0,0 +1,428 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_CRYPTO_AES
|
||||
|
||||
#include "crypt_aes_macro_armv8.s"
|
||||
.file "crypt_aes_armv8.S"
|
||||
.text
|
||||
.arch armv8-a+crypto
|
||||
|
||||
KEY .req x0
|
||||
IN .req x1
|
||||
OUT .req x2
|
||||
|
||||
ROUNDS .req w6
|
||||
|
||||
RDK0 .req v17
|
||||
RDK1 .req v18
|
||||
|
||||
.section .rodata
|
||||
.align 5
|
||||
.g_cron:
|
||||
.long 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
|
||||
.align 5
|
||||
|
||||
/*
|
||||
* In Return-oriented programming (ROP) and Jump-oriented programming (JOP), we explored features
|
||||
* that Arm introduced to the Arm architecture to mitigate against JOP-style and ROP-style attacks.
|
||||
* ...
|
||||
* Whether the combined or NOP-compatible instructions are set depends on the architecture
|
||||
* version that the code is built for. When building for Armv8.3-A, or later, the compiler will use
|
||||
* the combined operations. When building for Armv8.2-A, or earlier, it will use the NOP compatible
|
||||
* instructions.
|
||||
*
|
||||
* The paciasp and autiasp instructions are used for function pointer authentication.
|
||||
* The pointer authentication feature is added in armv8.3 and is supported only by AArch64.
|
||||
* The addition of pointer authentication features is described in Section A2.6.1 of
|
||||
* DDI0487H_a_a-profile_architecture_reference_manual.pdf.
|
||||
*/
|
||||
|
||||
/*
|
||||
* int32_t CRYPT_AES_Encrypt(const CRYPT_AES_Key *ctx,
|
||||
* const uint8_t *in,
|
||||
* uint8_t *out,
|
||||
* uint32_t len);
|
||||
*/
|
||||
.text
|
||||
.globl CRYPT_AES_Encrypt
|
||||
.type CRYPT_AES_Encrypt, %function
|
||||
.align 5
|
||||
CRYPT_AES_Encrypt:
|
||||
.ecb_aesenc_start:
|
||||
.inst 0xd503233f // paciasp
|
||||
stp x29, x30, [sp, #-16]!
|
||||
add x29, sp, #0
|
||||
|
||||
ld1 {BLK0.16b}, [IN]
|
||||
AES_ENC_1_BLK KEY BLK0.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b}, [OUT]
|
||||
|
||||
eor x0, x0, x0
|
||||
eor RDK0.16b, RDK0.16b, RDK0.16b
|
||||
eor RDK1.16b, RDK1.16b, RDK1.16b
|
||||
ldp x29, x30, [sp], #16
|
||||
.inst 0xd50323bf // autiasp
|
||||
ret
|
||||
.size CRYPT_AES_Encrypt, .-CRYPT_AES_Encrypt
|
||||
|
||||
/*
|
||||
* int32_t CRYPT_AES_Decrypt(const CRYPT_AES_Key *ctx,
|
||||
* const uint8_t *in,
|
||||
* uint8_t *out,
|
||||
* uint32_t len);
|
||||
*/
|
||||
.globl CRYPT_AES_Decrypt
|
||||
.type CRYPT_AES_Decrypt, %function
|
||||
.align 5
|
||||
CRYPT_AES_Decrypt:
|
||||
.ecb_aesdec_start:
|
||||
.inst 0xd503233f // paciasp
|
||||
stp x29, x30, [sp, #-16]!
|
||||
add x29, sp, #0
|
||||
|
||||
ld1 {BLK0.16b}, [IN]
|
||||
AES_DEC_1_BLK KEY BLK0.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b}, [OUT]
|
||||
|
||||
eor x0, x0, x0
|
||||
eor RDK0.16b, RDK0.16b, RDK0.16b
|
||||
eor RDK1.16b, RDK1.16b, RDK1.16b
|
||||
ldp x29, x30, [sp], #16
|
||||
.inst 0xd50323bf // autiasp
|
||||
ret
|
||||
.size CRYPT_AES_Decrypt, .-CRYPT_AES_Decrypt
|
||||
|
||||
/*
|
||||
* void SetEncryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key);
|
||||
* Generating extended keys.
|
||||
* x0 => CRYPT_AES_Key *ctx; x1 => const uint8_t *key
|
||||
*/
|
||||
.globl SetEncryptKey128
|
||||
.type SetEncryptKey128, %function
|
||||
.align 5
|
||||
SetEncryptKey128:
|
||||
.Lenc_key_128:
|
||||
.inst 0xd503233f // paciasp
|
||||
stp x29, x30, [sp, #-64]!
|
||||
add x29, sp, #0
|
||||
stp x25, x26, [sp, #16]
|
||||
stp x23, x24, [sp, #32]
|
||||
stp x21, x22, [sp, #48] // Register push stack completed.
|
||||
|
||||
adrp x23, .g_cron
|
||||
add x23, x23, :lo12:.g_cron // Round key start address.
|
||||
mov x24, x0 // Copy key string address. The address increases by 16 bytes.
|
||||
ld1 {v1.16b}, [x1] // Reads the 16-byte key of a user.
|
||||
mov w26, #10 // Number of encryption rounds, which is filled
|
||||
// with rounds in the structure.
|
||||
st1 {v1.4s}, [x0], #16 // Save the first key.
|
||||
eor v0.16b, v0.16b, v0.16b // Clear zeros in V0.
|
||||
mov w25, #10 // loop for 10 times.
|
||||
.Lenc_key_128_loop:
|
||||
ldr w21, [x23], #4 // Obtains the round constant.
|
||||
dup v1.4s, v1.s[3] // Repeated four times,The last word of v1 is changed to v1 (128 bits).
|
||||
ld1 {v2.4s}, [x24], #16 // Obtains the 4 words used for XOR.
|
||||
ext v1.16b, v1.16b, v1.16b, #1 // Byte loop.
|
||||
dup v3.4s, w21 // Repeat four times to change w21 to v3 (128 bits).
|
||||
aese v1.16b, v0.16b // Xor then shift then sbox (XOR operation with 0 is itself,
|
||||
// equivalent to omitting the XOR operation).
|
||||
subs w25, w25, #1 // Count of 10-round key extension.
|
||||
eor v1.16b, v1.16b, v3.16b // Round constant XOR.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (1).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 4321->3210.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (2).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 3210->2100.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (3).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 2100->1000.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (4).
|
||||
st1 {v1.4s}, [x0], #16 // Stores the newly calculated 4-bytes key data into the key string.
|
||||
b.ne .Lenc_key_128_loop // Loop jump.
|
||||
str w26, [x0, #64] // Fill in the number of rounds.
|
||||
eor x24, x24, x24 // Clear sensitivity.
|
||||
eor x0, x0, x0
|
||||
ldp x21, x22, [sp, #48]
|
||||
ldp x23, x24, [sp, #32]
|
||||
ldp x25, x26, [sp, #16]
|
||||
ldp x29, x30, [sp], #64 // Pop stack completed.
|
||||
.inst 0xd50323bf // autiasp
|
||||
ret
|
||||
.size SetEncryptKey128, .-SetEncryptKey128
|
||||
|
||||
|
||||
/*
|
||||
* void SetDecryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key);
|
||||
* Set a decryption key string.
|
||||
* x0 => CRYPT_AES_Key *ctx; x1 => const uint8_t *key
|
||||
*/
|
||||
.globl SetDecryptKey128
|
||||
.type SetDecryptKey128, %function
|
||||
.align 5
|
||||
SetDecryptKey128:
|
||||
.inst 0xd503233f // paciasp
|
||||
stp x29, x30, [sp, #-32]!
|
||||
add x29, sp, #0
|
||||
stp x25, x28, [sp, #16] // Register push stack completed.
|
||||
|
||||
mov x28, x0
|
||||
bl .Lenc_key_128
|
||||
ld1 {v0.4s}, [x28], #16
|
||||
SETDECKEY_LDR_9_BLOCK x28
|
||||
ld1 {v10.4s}, [x28]
|
||||
mov x25, #-16
|
||||
SETDECKEY_INVMIX_9_BLOCK
|
||||
st1 {v0.4s}, [x28], x25
|
||||
SETDECKEY_STR_9_BLOCK x28, x25
|
||||
st1 {v10.4s}, [x28]
|
||||
eor x28, x28, x28
|
||||
eor x0, x0, x0
|
||||
ldp x25, x28, [sp, #16]
|
||||
ldp x29, x30, [sp], #32 // Stacking completed.
|
||||
.inst 0xd50323bf // autiasp
|
||||
ret
|
||||
.size SetDecryptKey128, .-SetDecryptKey128
|
||||
|
||||
|
||||
/*
|
||||
* void SetEncryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key);
|
||||
* Generating extended keys.
|
||||
* x0 => CRYPT_AES_Key *ctx; x1 => const uint8_t *key
|
||||
*/
|
||||
.globl SetEncryptKey192
|
||||
.type SetEncryptKey192, %function
|
||||
.align 5
|
||||
SetEncryptKey192:
|
||||
.Lenc_key_192:
|
||||
.inst 0xd503233f // paciasp
|
||||
stp x29, x30, [sp, #-64]!
|
||||
add x29, sp, #0
|
||||
stp x25, x26, [sp, #16]
|
||||
stp x23, x24, [sp, #32]
|
||||
stp x21, x22, [sp, #48] // Register push stack completed.
|
||||
|
||||
mov x24, x0 // Copy key string address. The address increases by 16 bytes.
|
||||
ld1 {v0.16b}, [x1], #16 // Obtain the first 128-bit key.
|
||||
mov w26, #12 // Number of encryption rounds.
|
||||
st1 {v0.4s}, [x0], #16 // Store the first 128-bit key.
|
||||
ld1 {v1.8b}, [x1] // Obtains the last 64-bit key.
|
||||
adrp x23, .g_cron
|
||||
add x23, x23, :lo12:.g_cron // Round key start address.
|
||||
st1 {v1.2s}, [x0], #8 // Store the last 64-bit key.
|
||||
eor v0.16b, v0.16b, v0.16b // Clear zeros in V0.
|
||||
mov w25, #8 // loop for 8 times.
|
||||
.Lenc_key_192_loop:
|
||||
dup v1.4s, v1.s[1] // Repeated four times,The last word of v1 is changed to v1 (128 bits).
|
||||
subs w25, w25, #1 // Count of 8-round key extensions.
|
||||
ext v1.16b, v1.16b, v1.16b, #1 // Byte cycle.
|
||||
ldr w22, [x23], #4 // Obtains the round constant.
|
||||
aese v1.16b, v0.16b // Shift and sbox (XOR operation with 0 is itself,equivalent to omitting the XOR operation).
|
||||
dup v2.4s, w22 // Repeat 4 times. W22 becomes v2(128bit).
|
||||
eor v1.16b, v1.16b, v2.16b // Round constant XOR.
|
||||
ld1 {v2.4s}, [x24], #16 // Obtains the 4 words used for XOR
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (1).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 4321->3210.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (2).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 3210->2100.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (3).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 2100->1000.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (4).
|
||||
st1 {v1.4s}, [x0], #16 // Stores the newly calculated 4-word key data into the key string.
|
||||
ld1 {v2.2s}, [x24], #8 // Loads 6 words for the last 2 words of XOR.
|
||||
dup v1.2s, v1.s[3] // Repeated two times,The last word of v1 is changed to v1 (64bit).
|
||||
eor v1.8b, v1.8b, v2.8b // 2 XOR operation (1).
|
||||
ext v2.8b, v0.8b, v2.8b, #4 // 21->10.
|
||||
eor v1.8b, v1.8b, v2.8b // 2 XOR operation (2).
|
||||
st1 {v1.2s}, [x0], #8 // Stores the newly calculated 2-word key data into the key string.
|
||||
b.ne .Lenc_key_192_loop // Loop jump.
|
||||
str w26, [x0, #24] // Fill in the number of rounds.
|
||||
eor x24, x24, x24 // Clear sensitivity.
|
||||
eor x0, x0, x0
|
||||
ldp x21, x22, [sp, #48]
|
||||
ldp x23, x24, [sp, #32]
|
||||
ldp x25, x26, [sp, #16]
|
||||
ldp x29, x30, [sp], #64 // Stacking completed.
|
||||
.inst 0xd50323bf // autiasp
|
||||
ret
|
||||
.size SetEncryptKey192, .-SetEncryptKey192
|
||||
|
||||
|
||||
/*
|
||||
* void SetDecryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key);
|
||||
* Set a decryption key string.
|
||||
* x0 => CRYPT_AES_Key *ctx; x1 => const uint8_t *key
|
||||
*/
|
||||
.globl SetDecryptKey192
|
||||
.type SetDecryptKey192, %function
|
||||
.align 5
|
||||
SetDecryptKey192:
|
||||
.inst 0xd503233f // paciasp
|
||||
stp x29, x30, [sp, #-32]!
|
||||
add x29, sp, #0
|
||||
stp x25, x28, [sp, #16] // Register is stacked.
|
||||
|
||||
mov x28, x0
|
||||
bl .Lenc_key_192
|
||||
mov x25, #-16
|
||||
ld1 {v0.4s}, [x28], #16
|
||||
SETDECKEY_LDR_9_BLOCK x28
|
||||
ld1 {v10.4s}, [x28], #16
|
||||
ld1 {v11.4s}, [x28], #16
|
||||
ld1 {v12.4s}, [x28]
|
||||
SETDECKEY_INVMIX_9_BLOCK
|
||||
aesimc v10.16b, v10.16b
|
||||
aesimc v11.16b, v11.16b
|
||||
st1 {v0.4s}, [x28], x25
|
||||
SETDECKEY_STR_9_BLOCK x28, x25
|
||||
st1 {v10.4s}, [x28], x25
|
||||
st1 {v11.4s}, [x28], x25
|
||||
st1 {v12.4s}, [x28]
|
||||
eor x28, x28, x28
|
||||
eor x0, x0, x0
|
||||
ldp x25, x28, [sp, #16]
|
||||
ldp x29, x30, [sp], #32 // Stacking completed.
|
||||
.inst 0xd50323bf // autiasp
|
||||
ret
|
||||
.size SetDecryptKey192, .-SetDecryptKey192
|
||||
|
||||
/*
|
||||
* void SetEncryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key);
|
||||
* Generating extended keys.
|
||||
* x0 => CRYPT_AES_Key *ctx; x1 => const uint8_t *key
|
||||
*/
|
||||
.globl SetEncryptKey256
|
||||
.type SetEncryptKey256, %function
|
||||
.align 5
|
||||
SetEncryptKey256:
|
||||
.Lenc_key_256:
|
||||
.inst 0xd503233f // paciasp
|
||||
stp x29, x30, [sp, #-64]!
|
||||
add x29, sp, #0
|
||||
stp x25, x26, [sp, #16]
|
||||
stp x23, x24, [sp, #32]
|
||||
stp x21, x22, [sp, #48] // Register is stacked.
|
||||
|
||||
adrp x23, .g_cron
|
||||
add x23, x23, :lo12:.g_cron // Round key start address.
|
||||
ld1 {v0.16b}, [x1], #16 // Obtain the first 128-bit key.
|
||||
mov x24, x0 // Copy key string address. The address increases by 16 bytes.
|
||||
st1 {v0.4s}, [x0], #16 // Store the first 128-bit key.
|
||||
ld1 {v1.16b}, [x1] // Obtain the last 128-bit key.
|
||||
eor v0.16b, v0.16b, v0.16b // Clear zeros in V0.
|
||||
st1 {v1.4s}, [x0], #16 // Store the last 128-bit key.
|
||||
mov w26, #14 // Number of encryption rounds.
|
||||
mov w25, #6 // Loop for 7-1 times.
|
||||
.Lenc_key_256_loop:
|
||||
dup v1.4s, v1.s[3] // Repeated four times,The last word of v1 is changed to v1 (128 bits).
|
||||
ldr w22, [x23], #4 // Obtains the round constant.
|
||||
ext v1.16b, v1.16b, v1.16b, #1 // Byte cycle.
|
||||
aese v1.16b, v0.16b // XOR then shift then sbox (XOR operation with 0 is itself,
|
||||
// equivalent to omitting the XOR operation).
|
||||
dup v2.4s, w22 // Repeat 4 times. w22 becomes v2.
|
||||
eor v1.16b, v1.16b, v2.16b // Round constant XOR.
|
||||
ld1 {v2.4s}, [x24], #16 // Obtains the 4 words used for XOR.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (1).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 4321->3210.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (2).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 3210->2100.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (3).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 2100->1000.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (4).
|
||||
st1 {v1.4s}, [x0], #16 // Stores the newly calculated 4-word key data into the key string.
|
||||
subs w25, w25, #1 // Count of 7-1-round key extensions.
|
||||
dup v1.4s, v1.s[3] // Repeated four times,The last word of v1 is changed to v1 (128 bits).
|
||||
ld1 {v2.4s}, [x24], #16 // Obtains the 4 words used for XOR.
|
||||
aese v1.16b, v0.16b // XOR then shift then sbox.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (1).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 4321->3210.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (2).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 3210->2100.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (3).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 2100->1000.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (4).
|
||||
st1 {v1.4s}, [x0], #16 // Stores the newly calculated 4-word key data into the key string.
|
||||
b.ne .Lenc_key_256_loop // Loop jump.
|
||||
|
||||
dup v1.4s, v1.s[3] // Repeated four times,The last word of v1 is changed to v1 (128 bits).
|
||||
ldr w22, [x23], #4 // Obtains the round constant.
|
||||
ext v1.16b, v1.16b, v1.16b, #1 // Byte cycle.
|
||||
aese v1.16b, v0.16b // XOR then shift then sbox.
|
||||
dup v2.4s, w22 // Repeat 4 times. w22 becomes v2(128bit).
|
||||
eor v1.16b, v1.16b, v2.16b // Round constant XOR.
|
||||
ld1 {v2.4s}, [x24], #16 // Obtains the 4 words used for XOR.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (1).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 4321->3210.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (2).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 3210->2100.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (3).
|
||||
ext v2.16b, v0.16b, v2.16b, #12 // 2100->1000.
|
||||
eor v1.16b, v1.16b, v2.16b // 4 XOR operation (4).
|
||||
st1 {v1.4s}, [x0], #16 // Stores the newly calculated 4-word key data into the key string.
|
||||
str w26, [x0] // Fill in the number of rounds.
|
||||
eor x24, x24, x24 // Clear sensitivity.
|
||||
eor x0, x0, x0
|
||||
ldp x21, x22, [sp, #48]
|
||||
ldp x23, x24, [sp, #32]
|
||||
ldp x25, x26, [sp, #16]
|
||||
ldp x29, x30, [sp], #64 // Stacking completed.
|
||||
.inst 0xd50323bf // autiasp
|
||||
ret
|
||||
.size SetEncryptKey256, .-SetEncryptKey256
|
||||
|
||||
/*
|
||||
* void SetDecryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key);
|
||||
* Set a decryption key string.
|
||||
* x0 => CRYPT_AES_Key *ctx; x1 => const uint8_t *key
|
||||
*/
|
||||
.globl SetDecryptKey256
|
||||
.type SetDecryptKey256, %function
|
||||
.align 5
|
||||
SetDecryptKey256:
|
||||
.inst 0xd503233f // paciasp
|
||||
stp x29, x30, [sp, #-32]!
|
||||
add x29, sp, #0
|
||||
stp x25, x28, [sp, #16]
|
||||
|
||||
mov x28, x0
|
||||
bl .Lenc_key_256
|
||||
mov x25, #-16
|
||||
ld1 {v0.4s}, [x28], #16
|
||||
SETDECKEY_LDR_9_BLOCK x28
|
||||
ld1 {v10.4s}, [x28], #16
|
||||
ld1 {v11.4s}, [x28], #16
|
||||
ld1 {v12.4s}, [x28], #16
|
||||
ld1 {v13.4s}, [x28], #16
|
||||
ld1 {v14.4s}, [x28]
|
||||
SETDECKEY_INVMIX_9_BLOCK
|
||||
aesimc v10.16b, v10.16b
|
||||
aesimc v11.16b, v11.16b
|
||||
aesimc v12.16b, v12.16b
|
||||
aesimc v13.16b, v13.16b
|
||||
st1 {v0.4s}, [x28], x25
|
||||
SETDECKEY_STR_9_BLOCK x28, x25
|
||||
st1 {v10.4s}, [x28], x25
|
||||
st1 {v11.4s}, [x28], x25
|
||||
st1 {v12.4s}, [x28], x25
|
||||
st1 {v13.4s}, [x28], x25
|
||||
st1 {v14.4s}, [x28]
|
||||
eor x28, x28, x28
|
||||
eor x0, x0, x0
|
||||
ldp x25, x28, [sp, #16]
|
||||
ldp x29, x30, [sp], #32 // Stack has been popped.
|
||||
.inst 0xd50323bf // autiasp
|
||||
ret
|
||||
.size SetDecryptKey256, .-SetDecryptKey256
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,482 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_CBC)
|
||||
|
||||
#include "crypt_aes_macro_armv8.s"
|
||||
|
||||
.file "crypt_aes_cbc_armv8.S"
|
||||
.text
|
||||
.arch armv8-a+crypto
|
||||
|
||||
KEY .req x0
|
||||
IN .req x1
|
||||
OUT .req x2
|
||||
LEN .req x3
|
||||
P_IV .req x4
|
||||
|
||||
KTMP .req x5
|
||||
ROUNDS .req w6
|
||||
|
||||
BLK0 .req v0
|
||||
BLK1 .req v1
|
||||
BLK2 .req v2
|
||||
BLK3 .req v3
|
||||
BLK4 .req v4
|
||||
BLK5 .req v5
|
||||
BLK6 .req v6
|
||||
BLK7 .req v7
|
||||
|
||||
KEY0_END .req v16
|
||||
KEY0 .req v17
|
||||
KEY1 .req v18
|
||||
KEY2 .req v19
|
||||
KEY3 .req v20
|
||||
KEY4 .req v21
|
||||
KEY5 .req v22
|
||||
KEY6 .req v23
|
||||
KEY7 .req v24
|
||||
KEY8 .req v25
|
||||
KEY9 .req v26
|
||||
KEY10 .req v27
|
||||
KEY11 .req v28
|
||||
KEY12 .req v29
|
||||
KEY13 .req v30
|
||||
KEY14 .req v31
|
||||
|
||||
IVENC .req v1
|
||||
IV0 .req v17
|
||||
IV1 .req v18
|
||||
IV2 .req v19
|
||||
IV3 .req v20
|
||||
IV4 .req v21
|
||||
IV5 .req v22
|
||||
IV6 .req v23
|
||||
IV7 .req v24
|
||||
IVT .req v25
|
||||
|
||||
RDK0 .req v26
|
||||
RDK1 .req v27
|
||||
RDK2 .req v28
|
||||
|
||||
/*
|
||||
* One round of encryption process.
|
||||
* block:input the plaintext.
|
||||
* key: One round key.
|
||||
*/
|
||||
.macro ROUND block, key
|
||||
aese \block, \key
|
||||
aesmc \block, \block
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Eight blocks of decryption.
|
||||
* block0_7:Input the ciphertext.
|
||||
* rdk0: Round key.
|
||||
* ktmp: Temporarily stores pointers to keys.
|
||||
*/
|
||||
.macro DEC8 rdk0s rdk0 blk0 blk1 blk2 blk3 blk4 blk5 blk6 blk7 ktmp
|
||||
aesd \blk0, \rdk0
|
||||
aesimc \blk0, \blk0
|
||||
aesd \blk5, \rdk0
|
||||
aesimc \blk5, \blk5
|
||||
aesd \blk1, \rdk0
|
||||
aesimc \blk1, \blk1
|
||||
aesd \blk6, \rdk0
|
||||
aesimc \blk6, \blk6
|
||||
aesd \blk2, \rdk0
|
||||
aesimc \blk2, \blk2
|
||||
aesd \blk3, \rdk0
|
||||
aesimc \blk3, \blk3
|
||||
aesd \blk4, \rdk0
|
||||
aesimc \blk4, \blk4
|
||||
aesd \blk7, \rdk0
|
||||
aesimc \blk7, \blk7
|
||||
ld1 {\rdk0s}, [\ktmp], #16
|
||||
.endm
|
||||
|
||||
/**
|
||||
* Function description: AES encrypted assembly acceleration API in CBC mode.
|
||||
* int32_t CRYPT_AES_CBC_Encrypt(const CRYPT_AES_Key *ctx,
|
||||
* const uint8_t *in,
|
||||
* uint8_t *out,
|
||||
* uint32_t len,
|
||||
* uint8_t *iv);
|
||||
* Input register:
|
||||
* x0:Pointer to the input key structure
|
||||
* x1:points to the input data address
|
||||
* x2:points to the output data address
|
||||
* x3:Length of the input data, which must be a multiple of 16
|
||||
* x4:Points to the CBC mode mask address
|
||||
* Change register:x5, x6, v0-v31
|
||||
* Output register:x0
|
||||
* Function/Macro Call: None
|
||||
*/
|
||||
.globl CRYPT_AES_CBC_Encrypt
|
||||
.type CRYPT_AES_CBC_Encrypt, %function
|
||||
CRYPT_AES_CBC_Encrypt:
|
||||
.inst 0xd503233f // paciasp
|
||||
ld1 {IVENC.16b}, [P_IV] // load IV
|
||||
ldr w6, [KEY, #240] // load rounds
|
||||
ld1 {BLK0.16b}, [IN], #16 // load in
|
||||
ld1 {KEY0.4s, KEY1.4s}, [KEY], #32 // load keys
|
||||
cmp w6, #12
|
||||
ld1 {KEY2.4s, KEY3.4s}, [KEY], #32
|
||||
ld1 {KEY4.4s, KEY5.4s}, [KEY], #32
|
||||
ld1 {KEY6.4s, KEY7.4s}, [KEY], #32
|
||||
ld1 {KEY8.4s, KEY9.4s}, [KEY], #32
|
||||
eor IVENC.16b, IVENC.16b, BLK0.16b // iv + in
|
||||
b.lt .Laes_cbc_128_start
|
||||
|
||||
ld1 {KEY10.4s, KEY11.4s}, [KEY], #32
|
||||
b.eq .Laes_cbc_192_start
|
||||
ld1 {KEY12.4s, KEY13.4s}, [KEY], #32
|
||||
|
||||
.Laes_cbc_256_start:
|
||||
ld1 {KEY14.4s}, [KEY]
|
||||
ROUND IVENC.16b, KEY0.16b
|
||||
eor KEY0_END.16b, KEY0.16b, KEY14.16b // key0 + keyEnd
|
||||
b .Laes_cbc_256_round_loop
|
||||
|
||||
.Laes_cbc_256_loop:
|
||||
ROUND IVENC.16b, KEY0.16b
|
||||
st1 {BLK0.16b}, [OUT], #16
|
||||
|
||||
.Laes_cbc_256_round_loop:
|
||||
ROUND IVENC.16b, KEY1.16b
|
||||
ROUND IVENC.16b, KEY2.16b
|
||||
subs LEN, LEN, #16
|
||||
ROUND IVENC.16b, KEY3.16b
|
||||
ROUND IVENC.16b, KEY4.16b
|
||||
ROUND IVENC.16b, KEY5.16b
|
||||
ld1 {KEY0.16b}, [IN], #16 // load IN
|
||||
ROUND IVENC.16b, KEY6.16b
|
||||
ROUND IVENC.16b, KEY7.16b
|
||||
ROUND IVENC.16b, KEY8.16b
|
||||
ROUND IVENC.16b, KEY9.16b
|
||||
ROUND IVENC.16b, KEY10.16b
|
||||
ROUND IVENC.16b, KEY11.16b
|
||||
ROUND IVENC.16b, KEY12.16b
|
||||
aese IVENC.16b, KEY13.16b
|
||||
eor KEY0.16b, KEY0.16b, KEY0_END.16b // IN + KEY0 + KEYEND
|
||||
eor BLK0.16b, IVENC.16b, KEY14.16b
|
||||
b.gt .Laes_cbc_256_loop
|
||||
b .Lescbcenc_finish
|
||||
|
||||
.Laes_cbc_128_start:
|
||||
ld1 {KEY10.4s}, [KEY]
|
||||
ROUND IVENC.16b, KEY0.16b
|
||||
eor KEY0_END.16b, KEY0.16b, KEY10.16b // key0 + keyEnd
|
||||
b .Laes_cbc_128_round_loop
|
||||
|
||||
.Laes_cbc_128_loop:
|
||||
ROUND IVENC.16b, KEY0.16b
|
||||
st1 {BLK0.16b}, [OUT], #16
|
||||
|
||||
.Laes_cbc_128_round_loop:
|
||||
ROUND IVENC.16b, KEY1.16b
|
||||
ROUND IVENC.16b, KEY2.16b
|
||||
subs LEN, LEN, #16
|
||||
ROUND IVENC.16b, KEY3.16b
|
||||
ROUND IVENC.16b, KEY4.16b
|
||||
ROUND IVENC.16b, KEY5.16b
|
||||
ld1 {KEY0.16b}, [IN], #16 // load IN
|
||||
ROUND IVENC.16b, KEY6.16b
|
||||
ROUND IVENC.16b, KEY7.16b
|
||||
ROUND IVENC.16b, KEY8.16b
|
||||
aese IVENC.16b, KEY9.16b
|
||||
eor KEY0.16b, KEY0.16b, KEY0_END.16b // IN + KEY0 + KEYEND
|
||||
eor BLK0.16b, IVENC.16b, KEY10.16b // enc OK
|
||||
b.gt .Laes_cbc_128_loop
|
||||
b .Lescbcenc_finish
|
||||
|
||||
.Laes_cbc_192_start:
|
||||
ld1 {KEY12.4s}, [KEY]
|
||||
ROUND IVENC.16b, KEY0.16b
|
||||
eor KEY0_END.16b, KEY0.16b, KEY12.16b // key0 + keyEnd
|
||||
b .Laes_cbc_192_round_loop
|
||||
|
||||
.Laes_cbc_192_loop:
|
||||
ROUND IVENC.16b, KEY0.16b
|
||||
st1 {BLK0.16b}, [OUT], #16
|
||||
|
||||
.Laes_cbc_192_round_loop:
|
||||
ROUND IVENC.16b, KEY1.16b
|
||||
ROUND IVENC.16b, KEY2.16b
|
||||
subs LEN, LEN, #16
|
||||
ROUND IVENC.16b, KEY3.16b
|
||||
ROUND IVENC.16b, KEY4.16b
|
||||
ROUND IVENC.16b, KEY5.16b
|
||||
ld1 {KEY0.16b}, [IN], #16 // load IN
|
||||
ROUND IVENC.16b, KEY6.16b
|
||||
ROUND IVENC.16b, KEY7.16b
|
||||
ROUND IVENC.16b, KEY8.16b
|
||||
ROUND IVENC.16b, KEY9.16b
|
||||
ROUND IVENC.16b, KEY10.16b
|
||||
aese IVENC.16b, KEY11.16b
|
||||
eor KEY0.16b, KEY0.16b, KEY0_END.16b // IN + KEY0 + KEYEND
|
||||
eor BLK0.16b, IVENC.16b, KEY12.16b
|
||||
b.gt .Laes_cbc_192_loop
|
||||
|
||||
.Lescbcenc_finish:
|
||||
st1 {BLK0.16b}, [OUT], #16
|
||||
st1 {BLK0.16b}, [P_IV]
|
||||
mov x0, #0
|
||||
.inst 0xd50323bf // autiasp
|
||||
ret
|
||||
.size CRYPT_AES_CBC_Encrypt, .-CRYPT_AES_CBC_Encrypt
|
||||
|
||||
/**
|
||||
* Function description: AES decryption and assembly acceleration API in CBC mode.
|
||||
* int32_t CRYPT_AES_CBC_Decrypt(const CRYPT_AES_Key *ctx,
|
||||
* const uint8_t *in,
|
||||
* uint8_t *out,
|
||||
* uint32_t len,
|
||||
* uint8_t *iv);
|
||||
* Input register:
|
||||
* x0:pointer to the input key structure
|
||||
* x1:points to the input data address
|
||||
* x2:points to the output data address
|
||||
* x3:Length of the input data, which must be a multiple of 16
|
||||
* x4:Points to the CBC mode mask address
|
||||
* Change register:x5, x6, v0-v31
|
||||
* Output register:x0
|
||||
* Function/Macro Call: AES_DEC_8_BLKS, AES_DEC_1_BLK, AES_DEC_2_BLKS, AES_DEC_3_BLKS,
|
||||
* AES_DEC_4_BLKS, AES_DEC_5_BLKS, AES_DEC_6_BLKS, AES_DEC_7_BLKS
|
||||
*/
|
||||
.globl CRYPT_AES_CBC_Decrypt
|
||||
.type CRYPT_AES_CBC_Decrypt, %function
|
||||
CRYPT_AES_CBC_Decrypt:
|
||||
.inst 0xd503233f // paciasp
|
||||
ld1 {IV0.16b}, [P_IV]
|
||||
.Lcbc_aesdec_start:
|
||||
cmp LEN, #64
|
||||
b.ge .Lcbc_dec_above_equal_4_blks
|
||||
cmp LEN, #32
|
||||
b.ge .Lcbc_dec_above_equal_2_blks
|
||||
cmp LEN, #0
|
||||
b.eq .Lcbc_aesdec_finish
|
||||
b .Lcbc_dec_proc_1_blk
|
||||
|
||||
.Lcbc_dec_above_equal_2_blks:
|
||||
cmp LEN, #48
|
||||
b.lt .Lcbc_dec_proc_2_blks
|
||||
b .Lcbc_dec_proc_3_blks
|
||||
|
||||
.Lcbc_dec_above_equal_4_blks:
|
||||
cmp LEN, #96
|
||||
b.ge .Lcbc_dec_above_equal_6_blks
|
||||
cmp LEN, #80
|
||||
b.lt .Lcbc_dec_proc_4_blks
|
||||
b .Lcbc_dec_proc_5_blks
|
||||
|
||||
.Lcbc_dec_above_equal_6_blks:
|
||||
cmp LEN, #112
|
||||
b.lt .Lcbc_dec_proc_6_blks
|
||||
cmp LEN, #128
|
||||
b.lt .Lcbc_dec_proc_7_blks
|
||||
|
||||
.align 4
|
||||
.Lcbc_aesdec_8_blks_loop:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
mov KTMP, KEY
|
||||
ldr ROUNDS, [KEY, #240]
|
||||
ld1 {BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b}, [IN], #64
|
||||
|
||||
mov IV1.16b, BLK0.16b
|
||||
mov IV2.16b, BLK1.16b
|
||||
mov IV3.16b, BLK2.16b
|
||||
ld1 {RDK0.4s, RDK1.4s}, [KTMP], #32
|
||||
mov IV4.16b, BLK3.16b
|
||||
mov IV5.16b, BLK4.16b
|
||||
mov IV6.16b, BLK5.16b
|
||||
mov IV7.16b, BLK6.16b
|
||||
mov IVT.16b, BLK7.16b
|
||||
|
||||
|
||||
DEC8 RDK0.4s, RDK0.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP
|
||||
DEC8 RDK1.4s, RDK1.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP
|
||||
DEC8 RDK0.4s, RDK0.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP
|
||||
DEC8 RDK1.4s, RDK1.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP
|
||||
DEC8 RDK0.4s, RDK0.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP
|
||||
DEC8 RDK1.4s, RDK1.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP
|
||||
DEC8 RDK0.4s, RDK0.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP
|
||||
DEC8 RDK1.4s, RDK1.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP
|
||||
|
||||
cmp ROUNDS, #12
|
||||
b.lt .Ldec_8_blks_last
|
||||
DEC8 RDK0.4s, RDK0.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP
|
||||
DEC8 RDK1.4s, RDK1.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP
|
||||
b.eq .Ldec_8_blks_last
|
||||
DEC8 RDK0.4s, RDK0.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP
|
||||
DEC8 RDK1.4s, RDK1.16b, BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b, BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b, KTMP
|
||||
|
||||
.Ldec_8_blks_last:
|
||||
ld1 {RDK2.4s}, [KTMP]
|
||||
aesd BLK0.16b, RDK0.16b
|
||||
aesimc BLK0.16b, BLK0.16b
|
||||
aesd BLK1.16b, RDK0.16b
|
||||
aesimc BLK1.16b, BLK1.16b
|
||||
aesd BLK2.16b, RDK0.16b
|
||||
aesimc BLK2.16b, BLK2.16b
|
||||
eor IV0.16b, IV0.16b, RDK2.16b
|
||||
aesd BLK3.16b, RDK0.16b
|
||||
aesimc BLK3.16b, BLK3.16b
|
||||
eor IV1.16b, IV1.16b, RDK2.16b
|
||||
aesd BLK4.16b, RDK0.16b
|
||||
aesimc BLK4.16b, BLK4.16b
|
||||
eor IV2.16b, IV2.16b, RDK2.16b
|
||||
aesd BLK5.16b, RDK0.16b
|
||||
aesimc BLK5.16b, BLK5.16b
|
||||
eor IV3.16b, IV3.16b, RDK2.16b
|
||||
aesd BLK6.16b, RDK0.16b
|
||||
aesimc BLK6.16b, BLK6.16b
|
||||
eor IV4.16b, IV4.16b, RDK2.16b
|
||||
aesd BLK7.16b, RDK0.16b
|
||||
aesimc BLK7.16b, BLK7.16b
|
||||
eor IV5.16b, IV5.16b, RDK2.16b
|
||||
|
||||
aesd BLK0.16b, RDK1.16b
|
||||
aesd BLK1.16b, RDK1.16b
|
||||
eor IV6.16b, IV6.16b, RDK2.16b
|
||||
aesd BLK2.16b, RDK1.16b
|
||||
aesd BLK3.16b, RDK1.16b
|
||||
eor IV7.16b, IV7.16b, RDK2.16b
|
||||
aesd BLK4.16b, RDK1.16b
|
||||
aesd BLK5.16b, RDK1.16b
|
||||
aesd BLK6.16b, RDK1.16b
|
||||
aesd BLK7.16b, RDK1.16b
|
||||
|
||||
sub LEN, LEN, #128
|
||||
eor BLK0.16b, BLK0.16b, IV0.16b
|
||||
eor BLK1.16b, BLK1.16b, IV1.16b
|
||||
eor BLK2.16b, BLK2.16b, IV2.16b
|
||||
eor BLK3.16b, BLK3.16b, IV3.16b
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
eor BLK4.16b, BLK4.16b, IV4.16b
|
||||
eor BLK5.16b, BLK5.16b, IV5.16b
|
||||
cmp LEN, #0
|
||||
eor BLK6.16b, BLK6.16b, IV6.16b
|
||||
eor BLK7.16b, BLK7.16b, IV7.16b
|
||||
mov IV0.16b, IVT.16b
|
||||
st1 {BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b}, [OUT], #64
|
||||
b.eq .Lcbc_aesdec_finish
|
||||
cmp LEN, #128
|
||||
b.lt .Lcbc_aesdec_start
|
||||
b .Lcbc_aesdec_8_blks_loop
|
||||
|
||||
.Lcbc_dec_proc_1_blk:
|
||||
ld1 {BLK0.16b}, [IN]
|
||||
AES_DEC_1_BLK KEY BLK0.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
eor BLK0.16b, BLK0.16b, IV0.16b
|
||||
ld1 {IV0.16b}, [IN]
|
||||
st1 {BLK0.16b}, [OUT]
|
||||
b .Lcbc_aesdec_finish
|
||||
|
||||
.Lcbc_dec_proc_2_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b}, [IN]
|
||||
ld1 {IV1.16b}, [IN], #16
|
||||
AES_DEC_2_BLKS KEY BLK0.16b BLK1.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
eor BLK0.16b, BLK0.16b, IV0.16b
|
||||
eor BLK1.16b, BLK1.16b, IV1.16b
|
||||
ld1 {IV0.16b}, [IN]
|
||||
st1 {BLK0.16b, BLK1.16b}, [OUT]
|
||||
b .Lcbc_aesdec_finish
|
||||
|
||||
.Lcbc_dec_proc_3_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b}, [IN]
|
||||
ld1 {IV1.16b, IV2.16b}, [IN], #32
|
||||
AES_DEC_3_BLKS KEY BLK0.16b BLK1.16b BLK2.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
eor BLK0.16b, BLK0.16b, IV0.16b
|
||||
eor BLK1.16b, BLK1.16b, IV1.16b
|
||||
eor BLK2.16b, BLK2.16b, IV2.16b
|
||||
ld1 {IV0.16b}, [IN]
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b}, [OUT]
|
||||
b .Lcbc_aesdec_finish
|
||||
|
||||
.Lcbc_dec_proc_4_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN]
|
||||
ld1 {IV1.16b, IV2.16b, IV3.16b}, [IN], #48
|
||||
AES_DEC_4_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
eor BLK0.16b, BLK0.16b, IV0.16b
|
||||
eor BLK1.16b, BLK1.16b, IV1.16b
|
||||
eor BLK2.16b, BLK2.16b, IV2.16b
|
||||
eor BLK3.16b, BLK3.16b, IV3.16b
|
||||
ld1 {IV0.16b}, [IN]
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT]
|
||||
b .Lcbc_aesdec_finish
|
||||
|
||||
.Lcbc_dec_proc_5_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN]
|
||||
ld1 {IV1.16b, IV2.16b, IV3.16b, IV4.16b}, [IN], #64
|
||||
ld1 {BLK4.16b}, [IN]
|
||||
AES_DEC_5_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b BLK4.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
eor BLK0.16b, BLK0.16b, IV0.16b
|
||||
eor BLK1.16b, BLK1.16b, IV1.16b
|
||||
eor BLK2.16b, BLK2.16b, IV2.16b
|
||||
eor BLK3.16b, BLK3.16b, IV3.16b
|
||||
eor BLK4.16b, BLK4.16b, IV4.16b
|
||||
ld1 {IV0.16b}, [IN]
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b}, [OUT]
|
||||
b .Lcbc_aesdec_finish
|
||||
|
||||
.Lcbc_dec_proc_6_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN]
|
||||
ld1 {IV1.16b, IV2.16b, IV3.16b, IV4.16b}, [IN], #64
|
||||
ld1 {BLK4.16b, BLK5.16b}, [IN]
|
||||
ld1 {IV5.16b}, [IN], #16
|
||||
AES_DEC_6_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b BLK4.16b BLK5.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
eor BLK0.16b, BLK0.16b, IV0.16b
|
||||
eor BLK1.16b, BLK1.16b, IV1.16b
|
||||
eor BLK2.16b, BLK2.16b, IV2.16b
|
||||
eor BLK3.16b, BLK3.16b, IV3.16b
|
||||
eor BLK4.16b, BLK4.16b, IV4.16b
|
||||
eor BLK5.16b, BLK5.16b, IV5.16b
|
||||
ld1 {IV0.16b}, [IN]
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b, BLK5.16b}, [OUT]
|
||||
b .Lcbc_aesdec_finish
|
||||
|
||||
.Lcbc_dec_proc_7_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN]
|
||||
ld1 {IV1.16b, IV2.16b, IV3.16b, IV4.16b}, [IN], #64
|
||||
ld1 {BLK4.16b, BLK5.16b, BLK6.16b}, [IN]
|
||||
ld1 {IV5.16b, IV6.16b}, [IN], #32
|
||||
AES_DEC_7_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b BLK4.16b BLK5.16b BLK6.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
eor BLK0.16b, BLK0.16b, IV0.16b
|
||||
eor BLK1.16b, BLK1.16b, IV1.16b
|
||||
eor BLK2.16b, BLK2.16b, IV2.16b
|
||||
eor BLK3.16b, BLK3.16b, IV3.16b
|
||||
eor BLK4.16b, BLK4.16b, IV4.16b
|
||||
eor BLK5.16b, BLK5.16b, IV5.16b
|
||||
eor BLK6.16b, BLK6.16b, IV6.16b
|
||||
|
||||
ld1 {IV0.16b}, [IN]
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b, BLK5.16b, BLK6.16b}, [OUT]
|
||||
|
||||
.Lcbc_aesdec_finish:
|
||||
st1 {IV0.16b}, [P_IV]
|
||||
mov x0, #0
|
||||
eor RDK0.16b, RDK0.16b, RDK0.16b
|
||||
eor RDK1.16b, RDK1.16b, RDK1.16b
|
||||
eor RDK2.16b, RDK2.16b, RDK2.16b
|
||||
.inst 0xd50323bf // autiasp
|
||||
ret
|
||||
.size CRYPT_AES_CBC_Decrypt, .-CRYPT_AES_CBC_Decrypt
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,499 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_CBC)
|
||||
|
||||
#include "crypt_aes_macro_x86_64.s"
|
||||
|
||||
.file "crypt_aes_cbc_x86_64.S"
|
||||
.text
|
||||
|
||||
.set ARG1, %rdi
|
||||
.set ARG2, %rsi
|
||||
.set ARG3, %rdx
|
||||
.set ARG4, %ecx
|
||||
.set ARG5, %r8
|
||||
.set ARG6, %r9
|
||||
|
||||
.set RDK, %xmm3
|
||||
.set KEY, %rdi
|
||||
.set KTMP, %r9
|
||||
.set ROUNDS, %eax
|
||||
.set RET, %eax
|
||||
|
||||
.set BLK0, %xmm1
|
||||
.set BLK1, %xmm4
|
||||
.set BLK2, %xmm5
|
||||
.set BLK3, %xmm6
|
||||
.set BLK4, %xmm10
|
||||
.set BLK5, %xmm11
|
||||
.set BLK6, %xmm12
|
||||
.set BLK7, %xmm13
|
||||
.set IV0, %xmm0
|
||||
.set IV1, %xmm7
|
||||
.set IV2, %xmm8
|
||||
.set IV3, %xmm9
|
||||
|
||||
.set KEY1, %xmm4
|
||||
.set KEY2, %xmm5
|
||||
.set KEY3, %xmm6
|
||||
.set KEY4, %xmm10
|
||||
.set KEY5, %xmm11
|
||||
.set KEY6, %xmm12
|
||||
.set KEY7, %xmm13
|
||||
.set KEY8, %xmm14
|
||||
.set KEY9, %xmm15
|
||||
.set KEY10, %xmm2
|
||||
.set KEY11, %xmm7
|
||||
.set KEY12, %xmm8
|
||||
.set KEY13, %xmm9
|
||||
.set KEYTEMP, %xmm3
|
||||
|
||||
/**
|
||||
* Function description:AES encrypted assembly acceleration API in CBC mode.
|
||||
* Function prototype:int32_t CRYPT_AES_CBC_Encrypt(const CRYPT_AES_Key *ctx,
|
||||
* const uint8_t *in,
|
||||
* uint8_t *out,
|
||||
* uint32_t len,
|
||||
* uint8_t *iv);
|
||||
* Input register:
|
||||
* rdi:pointer to the input key structure
|
||||
* rsi:points to the input data address
|
||||
* rdx:points to the output data address
|
||||
* rcx:Length of the input data, which must be a multiple of 16
|
||||
* r8: Points to the CBC mode mask address
|
||||
* Change register:xmm0-xmm15
|
||||
* Output register:eax
|
||||
* Function/Macro Call: None
|
||||
*/
|
||||
.globl CRYPT_AES_CBC_Encrypt
|
||||
.type CRYPT_AES_CBC_Encrypt, @function
|
||||
CRYPT_AES_CBC_Encrypt:
|
||||
.cfi_startproc
|
||||
.align 16
|
||||
cmpl $16, ARG4
|
||||
jb .Laescbcend_end
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (ARG5), IV0
|
||||
vmovdqu (KEY), KEY1
|
||||
vmovdqu 16(KEY), KEY2
|
||||
vmovdqu 32(KEY), KEY3
|
||||
vmovdqu 48(KEY), KEY4
|
||||
vmovdqu 64(KEY), KEY5
|
||||
vmovdqu 80(KEY), KEY6
|
||||
vmovdqu 96(KEY), KEY7
|
||||
vmovdqu 112(KEY), KEY8
|
||||
vmovdqu 128(KEY), KEY9
|
||||
vmovdqu 144(KEY), KEY10
|
||||
vmovdqu 160(KEY), KEY11
|
||||
cmpl $12, ROUNDS
|
||||
jb .Laes_128_cbc_start
|
||||
je .Laes_192_cbc_start
|
||||
.align 16
|
||||
.Laes_256_cbc_start:
|
||||
vmovdqu 176(KEY), KEY12
|
||||
vmovdqu 192(KEY), KEY13
|
||||
.Laes_256_cbc_loop:
|
||||
vpxor (ARG2), IV0, BLK0
|
||||
vmovdqu 208(KEY), KEYTEMP
|
||||
vpxor BLK0, KEY1, BLK0
|
||||
aesenc KEY2, BLK0
|
||||
aesenc KEY3, BLK0
|
||||
aesenc KEY4, BLK0
|
||||
aesenc KEY5, BLK0
|
||||
aesenc KEY6, BLK0
|
||||
aesenc KEY7, BLK0
|
||||
aesenc KEY8, BLK0
|
||||
aesenc KEY9, BLK0
|
||||
aesenc KEY10, BLK0
|
||||
aesenc KEY11, BLK0
|
||||
aesenc KEY12, BLK0
|
||||
aesenc KEY13, BLK0
|
||||
aesenc KEYTEMP, BLK0
|
||||
vmovdqu 224(KEY), KEYTEMP
|
||||
aesenclast KEYTEMP, BLK0
|
||||
leaq 16(ARG2), ARG2
|
||||
vmovdqu BLK0, (ARG3)
|
||||
movdqa BLK0, IV0
|
||||
leaq 16(ARG3), ARG3
|
||||
subl $16, ARG4
|
||||
cmpl $16, ARG4
|
||||
jnb .Laes_256_cbc_loop // Special value processing
|
||||
vpxor KEY12, KEY12, KEY12
|
||||
vpxor KEY13, KEY13, KEY13
|
||||
vpxor KEYTEMP, KEYTEMP, KEYTEMP
|
||||
jmp .Laescbcenc_finish
|
||||
|
||||
.align 16
|
||||
.Laes_192_cbc_start:
|
||||
vmovdqu 176(KEY), KEY12
|
||||
vmovdqu 192(KEY), KEY13
|
||||
.Laes_192_cbc_loop:
|
||||
vpxor (ARG2), IV0, BLK0
|
||||
vpxor BLK0, KEY1, BLK0
|
||||
aesenc KEY2, BLK0
|
||||
aesenc KEY3, BLK0
|
||||
aesenc KEY4, BLK0
|
||||
aesenc KEY5, BLK0
|
||||
aesenc KEY6, BLK0
|
||||
aesenc KEY7, BLK0
|
||||
aesenc KEY8, BLK0
|
||||
aesenc KEY9, BLK0
|
||||
aesenc KEY10, BLK0
|
||||
aesenc KEY11, BLK0
|
||||
aesenc KEY12, BLK0
|
||||
aesenclast KEY13, BLK0
|
||||
leaq 16(ARG2), ARG2
|
||||
vmovdqu BLK0, (ARG3)
|
||||
movdqa BLK0, IV0
|
||||
leaq 16(ARG3), ARG3
|
||||
subl $16 , ARG4
|
||||
jnz .Laes_192_cbc_loop
|
||||
vpxor KEY12, KEY12, KEY12
|
||||
vpxor KEY13, KEY13, KEY13
|
||||
jmp .Laescbcenc_finish
|
||||
|
||||
.align 16
|
||||
.Laes_128_cbc_start:
|
||||
vpxor (ARG2), IV0, BLK0
|
||||
vpxor BLK0, KEY1, BLK0
|
||||
aesenc KEY2, BLK0
|
||||
aesenc KEY3, BLK0
|
||||
aesenc KEY4, BLK0
|
||||
aesenc KEY5, BLK0
|
||||
aesenc KEY6, BLK0
|
||||
aesenc KEY7, BLK0
|
||||
aesenc KEY8, BLK0
|
||||
aesenc KEY9, BLK0
|
||||
aesenc KEY10, BLK0
|
||||
aesenclast KEY11, BLK0
|
||||
leaq 16(ARG2), ARG2
|
||||
vmovdqu BLK0, (ARG3)
|
||||
movdqa BLK0, IV0
|
||||
leaq 16(ARG3), ARG3
|
||||
subl $16, ARG4
|
||||
jnz .Laes_128_cbc_start
|
||||
jmp .Laescbcenc_finish
|
||||
|
||||
.Laescbcenc_finish:
|
||||
vmovdqu BLK0,(ARG5)
|
||||
vpxor KEY1, KEY1, KEY1
|
||||
vpxor KEY2, KEY2, KEY2
|
||||
vpxor KEY3, KEY3, KEY3
|
||||
vpxor KEY4, KEY4, KEY4
|
||||
vpxor KEY5, KEY5, KEY5
|
||||
vpxor KEY6, KEY6, KEY6
|
||||
vpxor KEY7, KEY7, KEY7
|
||||
vpxor KEY8, KEY8, KEY8
|
||||
vpxor KEY9, KEY9, KEY9
|
||||
vpxor KEY10, KEY10, KEY10
|
||||
vpxor KEY11, KEY11, KEY11
|
||||
.Laescbcend_end:
|
||||
movl $0, RET
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size CRYPT_AES_CBC_Encrypt, .-CRYPT_AES_CBC_Encrypt
|
||||
|
||||
/**
|
||||
* Function description: Sets the AES decryption and assembly accelerated implementation interface in CBC mode
|
||||
* Function prototype:int32_t CRYPT_AES_CBC_Decrypt(const CRYPT_AES_Key *ctx,
|
||||
* const uint8_t *in,
|
||||
* uint8_t *out,
|
||||
* uint32_t len,
|
||||
* uint8_t *iv);
|
||||
* Input register:
|
||||
* rdi:pointer to the input key structure
|
||||
* rsi:points to the input data address.
|
||||
* rdx:points to the output data address.
|
||||
* rcx:Length of the input data, which must be a multiple of 16
|
||||
* r8: Points to the CBC mode mask address
|
||||
* Change register:xmm0-xmm13
|
||||
* Output register:eax
|
||||
* Function/Macro Call: None
|
||||
*/
|
||||
.globl CRYPT_AES_CBC_Decrypt
|
||||
.type CRYPT_AES_CBC_Decrypt, @function
|
||||
CRYPT_AES_CBC_Decrypt:
|
||||
.cfi_startproc
|
||||
.align 16
|
||||
vmovdqu (ARG5), IV0
|
||||
.Laes_cbc_dec_start:
|
||||
cmpl $64, ARG4
|
||||
jae .Labove_equal_4_blks
|
||||
cmpl $32, ARG4
|
||||
jae .Labove_equal_2_blks
|
||||
cmpl $0, ARG4
|
||||
je .Laes_cbc_dec_finish
|
||||
jmp .Lproc_1_blk
|
||||
|
||||
.Labove_equal_2_blks:
|
||||
cmpl $48, ARG4
|
||||
jb .Lproc_2_blks
|
||||
jmp .Lproc_3_blks
|
||||
|
||||
.Labove_equal_4_blks:
|
||||
cmpl $96, ARG4
|
||||
jae .Labove_equal_6_blks
|
||||
cmpl $80, ARG4
|
||||
jb .Lproc_4_blks
|
||||
jmp .Lproc_5_blks
|
||||
|
||||
.Labove_equal_6_blks:
|
||||
cmpl $112, ARG4
|
||||
jb .Lproc_6_blks
|
||||
cmpl $128, ARG4
|
||||
jb .Lproc_7_blks
|
||||
|
||||
.align 16
|
||||
.Lproc_8_blks:
|
||||
.Laescbcdec_8_blks_loop:
|
||||
vmovdqu (ARG2), BLK0
|
||||
vmovdqu 16(ARG2), BLK1
|
||||
vmovdqu 32(ARG2), BLK2
|
||||
movdqa BLK0, IV1
|
||||
movdqa BLK1, IV2
|
||||
movdqa BLK2, IV3
|
||||
movq KEY, KTMP
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor BLK0, RDK, BLK0
|
||||
vpxor BLK1, RDK, BLK1
|
||||
vpxor BLK2, RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
vpxor 64(ARG2), RDK, BLK4
|
||||
vpxor 80(ARG2), RDK, BLK5
|
||||
vpxor 96(ARG2), RDK, BLK6
|
||||
vpxor 112(ARG2), RDK, BLK7
|
||||
decl ROUNDS
|
||||
AES_DEC_8_BLKS KTMP ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 BLK5 BLK6 BLK7
|
||||
vpxor BLK0, IV0, BLK0
|
||||
vpxor BLK1, IV1, BLK1
|
||||
vpxor BLK2, IV2, BLK2
|
||||
vpxor BLK3, IV3, BLK3
|
||||
vpxor 48(ARG2), BLK4, BLK4
|
||||
vpxor 64(ARG2), BLK5, BLK5
|
||||
vpxor 80(ARG2), BLK6, BLK6
|
||||
vpxor 96(ARG2), BLK7, BLK7
|
||||
vmovdqu 112(ARG2), IV0
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
vmovdqu BLK4, 64(ARG3)
|
||||
vmovdqu BLK5, 80(ARG3)
|
||||
vmovdqu BLK6, 96(ARG3)
|
||||
vmovdqu BLK7, 112(ARG3)
|
||||
subl $128, ARG4
|
||||
leaq 128(ARG2), ARG2
|
||||
leaq 128(ARG3), ARG3
|
||||
cmpl $128, ARG4
|
||||
jb .Laes_cbc_dec_start
|
||||
jmp .Laescbcdec_8_blks_loop
|
||||
|
||||
.align 16
|
||||
.Lproc_1_blk:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
decl ROUNDS
|
||||
AES_DEC_1_BLK KEY ROUNDS RDK BLK0
|
||||
vpxor BLK0, IV0, BLK0
|
||||
vmovdqu (ARG2), IV0
|
||||
vmovdqu BLK0, (ARG3)
|
||||
jmp .Laes_cbc_dec_finish
|
||||
|
||||
.align 16
|
||||
.Lproc_2_blks:
|
||||
vmovdqu (ARG2), BLK0
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
movdqa BLK0, IV1
|
||||
vpxor BLK0, RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
decl ROUNDS
|
||||
AES_DEC_2_BLKS KEY ROUNDS RDK BLK0 BLK1
|
||||
vpxor BLK0, IV0, BLK0
|
||||
vpxor BLK1, IV1, BLK1
|
||||
vmovdqu 16(ARG2), IV0
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
jmp .Laes_cbc_dec_finish
|
||||
|
||||
.align 16
|
||||
.Lproc_3_blks:
|
||||
vmovdqu (ARG2), BLK0
|
||||
vmovdqu 16(ARG2), BLK1
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
movdqa BLK0, IV1
|
||||
movdqa BLK1, IV2
|
||||
vpxor BLK0, RDK, BLK0
|
||||
vpxor BLK1, RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
decl ROUNDS
|
||||
AES_DEC_3_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2
|
||||
vpxor BLK0, IV0, BLK0
|
||||
vpxor BLK1, IV1, BLK1
|
||||
vpxor BLK2, IV2, BLK2
|
||||
vmovdqu 32(ARG2), IV0
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
jmp .Laes_cbc_dec_finish
|
||||
|
||||
.align 16
|
||||
.Lproc_4_blks:
|
||||
vmovdqu (ARG2), BLK0
|
||||
vmovdqu 16(ARG2), BLK1
|
||||
vmovdqu 32(ARG2), BLK2
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
movdqa BLK0, IV1
|
||||
movdqa BLK1, IV2
|
||||
movdqa BLK2, IV3
|
||||
vpxor BLK0, RDK, BLK0
|
||||
vpxor BLK1, RDK, BLK1
|
||||
vpxor BLK2, RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
decl ROUNDS
|
||||
AES_DEC_4_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3
|
||||
vpxor BLK0, IV0, BLK0
|
||||
vpxor BLK1, IV1, BLK1
|
||||
vpxor BLK2, IV2, BLK2
|
||||
vpxor BLK3, IV3, BLK3
|
||||
vmovdqu 48(ARG2), IV0
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
jmp .Laes_cbc_dec_finish
|
||||
|
||||
.align 16
|
||||
.Lproc_5_blks:
|
||||
vmovdqu (ARG2), BLK0
|
||||
vmovdqu 16(ARG2), BLK1
|
||||
vmovdqu 32(ARG2), BLK2
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
movdqa BLK0, IV1
|
||||
movdqa BLK1, IV2
|
||||
movdqa BLK2, IV3
|
||||
vpxor BLK0, RDK, BLK0
|
||||
vpxor BLK1, RDK, BLK1
|
||||
vpxor BLK2, RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
vpxor 64(ARG2), RDK, BLK4
|
||||
decl ROUNDS
|
||||
AES_DEC_5_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4
|
||||
vpxor BLK0, IV0, BLK0
|
||||
vpxor BLK1, IV1, BLK1
|
||||
vpxor BLK2, IV2, BLK2
|
||||
vpxor BLK3, IV3, BLK3
|
||||
vpxor 48(ARG2), BLK4, BLK4
|
||||
vmovdqu 64(ARG2), IV0
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
vmovdqu BLK4, 64(ARG3)
|
||||
jmp .Laes_cbc_dec_finish
|
||||
|
||||
.align 16
|
||||
.Lproc_6_blks:
|
||||
vmovdqu (ARG2), BLK0
|
||||
vmovdqu 16(ARG2), BLK1
|
||||
vmovdqu 32(ARG2), BLK2
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
movdqa BLK0, IV1
|
||||
movdqa BLK1, IV2
|
||||
movdqa BLK2, IV3
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
vpxor 64(ARG2), RDK, BLK4
|
||||
vpxor 80(ARG2), RDK, BLK5
|
||||
decl ROUNDS
|
||||
AES_DEC_6_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 BLK5
|
||||
vpxor BLK0, IV0, BLK0
|
||||
vpxor BLK1, IV1, BLK1
|
||||
vpxor BLK2, IV2, BLK2
|
||||
vpxor BLK3, IV3, BLK3
|
||||
vpxor 48(ARG2), BLK4, BLK4
|
||||
vpxor 64(ARG2), BLK5, BLK5
|
||||
vmovdqu 80(ARG2), IV0
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
vmovdqu BLK4, 64(ARG3)
|
||||
vmovdqu BLK5, 80(ARG3)
|
||||
jmp .Laes_cbc_dec_finish
|
||||
|
||||
.align 16
|
||||
.Lproc_7_blks:
|
||||
vmovdqu (ARG2), BLK0
|
||||
vmovdqu 16(ARG2), BLK1
|
||||
vmovdqu 32(ARG2), BLK2
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
movdqa BLK0, IV1
|
||||
movdqa BLK1, IV2
|
||||
movdqa BLK2, IV3
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
vpxor 64(ARG2), RDK, BLK4
|
||||
vpxor 80(ARG2), RDK, BLK5
|
||||
vpxor 96(ARG2), RDK, BLK6
|
||||
decl ROUNDS
|
||||
AES_DEC_7_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 BLK5 BLK6
|
||||
vpxor BLK0, IV0, BLK0
|
||||
vpxor BLK1, IV1, BLK1
|
||||
vpxor BLK2, IV2, BLK2
|
||||
vpxor BLK3, IV3, BLK3
|
||||
vpxor 48(ARG2), BLK4, BLK4
|
||||
vpxor 64(ARG2), BLK5, BLK5
|
||||
vpxor 80(ARG2), BLK6, BLK6
|
||||
vmovdqu 96(ARG2), IV0
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
vmovdqu BLK4, 64(ARG3)
|
||||
vmovdqu BLK5, 80(ARG3)
|
||||
vmovdqu BLK6, 96(ARG3)
|
||||
|
||||
.align 16
|
||||
.Laes_cbc_dec_finish:
|
||||
vmovdqu IV0, (ARG5)
|
||||
vpxor BLK0, BLK0, BLK0
|
||||
vpxor BLK1, BLK1, BLK1
|
||||
vpxor BLK2, BLK2, BLK2
|
||||
vpxor BLK3, BLK3, BLK3
|
||||
vpxor BLK4, BLK4, BLK4
|
||||
vpxor BLK5, BLK5, BLK5
|
||||
vpxor BLK6, BLK6, BLK6
|
||||
vpxor BLK7, BLK7, BLK7
|
||||
vpxor RDK, RDK, RDK
|
||||
movl $0, RET
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size CRYPT_AES_CBC_Decrypt, .-CRYPT_AES_CBC_Decrypt
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_CFB)
|
||||
|
||||
#include "crypt_aes_macro_armv8.s"
|
||||
|
||||
.file "crypt_aes_cfb_armv8.S"
|
||||
.text
|
||||
.arch armv8-a+crypto
|
||||
|
||||
.align 5
|
||||
|
||||
KEY .req x0
|
||||
IN .req x1
|
||||
OUT .req x2
|
||||
LEN .req x3
|
||||
IV .req x4
|
||||
|
||||
LTMP .req x12
|
||||
|
||||
IVC .req v19
|
||||
CT1 .req v20
|
||||
CT2 .req v21
|
||||
CT3 .req v22
|
||||
CT4 .req v23
|
||||
CT5 .req v24
|
||||
CT6 .req v25
|
||||
CT7 .req v26
|
||||
CT8 .req v27
|
||||
|
||||
BLK0 .req v0
|
||||
BLK1 .req v1
|
||||
BLK2 .req v2
|
||||
BLK3 .req v3
|
||||
BLK4 .req v4
|
||||
BLK5 .req v5
|
||||
BLK6 .req v6
|
||||
BLK7 .req v7
|
||||
|
||||
RDK0 .req v17
|
||||
RDK1 .req v18
|
||||
ROUNDS .req w6
|
||||
|
||||
/*
|
||||
* int32_t CRYPT_AES_CFB_Decrypt(const CRYPT_AES_Key *ctx,
|
||||
* const uint8_t *in,
|
||||
* uint8_t *out,
|
||||
* uint32_t len,
|
||||
* uint8_t *iv);
|
||||
*/
|
||||
|
||||
.globl CRYPT_AES_CFB_Decrypt
|
||||
.type CRYPT_AES_CFB_Decrypt, %function
|
||||
CRYPT_AES_CFB_Decrypt:
|
||||
.inst 0xd503233f // Paciasp
|
||||
ld1 {IVC.16b}, [IV] // Load the IV
|
||||
mov LTMP, LEN
|
||||
|
||||
.Lcfb_aesdec_start:
|
||||
cmp LTMP, #64
|
||||
b.ge .Lcfb_dec_above_equal_4_blks
|
||||
cmp LTMP, #32
|
||||
b.ge .Lcfb_dec_above_equal_2_blks
|
||||
cmp LTMP, #0
|
||||
b.eq .Lcfb_len_zero
|
||||
b .Lcfb_dec_proc_1_blk
|
||||
|
||||
.Lcfb_dec_above_equal_2_blks:
|
||||
cmp LTMP, #48
|
||||
b.lt .Lcfb_dec_proc_2_blks
|
||||
b .Lcfb_dec_proc_3_blks
|
||||
|
||||
.Lcfb_dec_above_equal_4_blks:
|
||||
cmp LTMP, #96
|
||||
b.ge .Lcfb_dec_above_equal_6_blks
|
||||
cmp LTMP, #80
|
||||
b.lt .Lcfb_dec_proc_4_blks
|
||||
b .Lcfb_dec_proc_5_blks
|
||||
|
||||
.Lcfb_dec_above_equal_6_blks:
|
||||
cmp LTMP, #112
|
||||
b.lt .Lcfb_dec_proc_6_blks
|
||||
cmp LTMP, #128
|
||||
b.lt .Lcfb_dec_proc_7_blks
|
||||
|
||||
.Lcfb_dec_proc_8_blks:
|
||||
|
||||
/* When the length is greater than or equal to 128, eight blocks loop is used */
|
||||
.Lcfb_aesdec_8_blks_loop:
|
||||
|
||||
/* Compute 8 CBF Decryption */
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b}, [IN], #64
|
||||
|
||||
mov CT1.16b, IVC.16b // Prevent the IV or BLK from being changed
|
||||
mov CT2.16b, BLK0.16b
|
||||
mov CT3.16b, BLK1.16b
|
||||
mov CT4.16b, BLK2.16b
|
||||
mov CT5.16b, BLK3.16b
|
||||
mov CT6.16b, BLK4.16b
|
||||
mov CT7.16b, BLK5.16b
|
||||
mov CT8.16b, BLK6.16b
|
||||
|
||||
mov x14, KEY // Prevent the key from being changed
|
||||
AES_ENC_8_BLKS x14 CT1.16b CT2.16b CT3.16b CT4.16b CT5.16b \
|
||||
CT6.16b CT7.16b CT8.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
|
||||
mov IVC.16b, BLK7.16b // Prepares for the next loop or update
|
||||
|
||||
eor BLK0.16b, BLK0.16b, CT1.16b
|
||||
eor BLK1.16b, BLK1.16b, CT2.16b
|
||||
eor BLK2.16b, BLK2.16b, CT3.16b
|
||||
eor BLK3.16b, BLK3.16b, CT4.16b
|
||||
eor BLK4.16b, BLK4.16b, CT5.16b
|
||||
eor BLK5.16b, BLK5.16b, CT6.16b
|
||||
eor BLK6.16b, BLK6.16b, CT7.16b
|
||||
eor BLK7.16b, BLK7.16b, CT8.16b
|
||||
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b}, [OUT], #64
|
||||
|
||||
sub LTMP, LTMP, #128
|
||||
cmp LTMP, #0
|
||||
b.eq .Lcfb_aesdec_finish
|
||||
|
||||
cmp LTMP, #128
|
||||
b.lt .Lcfb_aesdec_start
|
||||
b .Lcfb_aesdec_8_blks_loop
|
||||
|
||||
.Lcfb_dec_proc_1_blk:
|
||||
ld1 {BLK0.16b}, [IN]
|
||||
mov CT1.16b, IVC.16b
|
||||
|
||||
AES_ENC_1_BLK KEY CT1.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
mov IVC.16b, BLK0.16b
|
||||
eor BLK0.16b, CT1.16b, BLK0.16b
|
||||
st1 {BLK0.16b}, [OUT]
|
||||
b .Lcfb_aesdec_finish
|
||||
|
||||
.Lcfb_dec_proc_2_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b}, [IN]
|
||||
mov CT1.16b, IVC.16b
|
||||
mov CT2.16b, BLK0.16b
|
||||
|
||||
AES_ENC_2_BLKS KEY CT1.16b CT2.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
mov IVC.16b, BLK1.16b
|
||||
eor BLK0.16b, CT1.16b, BLK0.16b
|
||||
eor BLK1.16b, CT2.16b, BLK1.16b
|
||||
|
||||
st1 {BLK0.16b, BLK1.16b}, [OUT]
|
||||
b .Lcfb_aesdec_finish
|
||||
|
||||
.Lcfb_dec_proc_3_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b}, [IN]
|
||||
mov CT1.16b, IVC.16b
|
||||
mov CT2.16b, BLK0.16b
|
||||
mov CT3.16b, BLK1.16b
|
||||
AES_ENC_3_BLKS KEY CT1.16b CT2.16b CT3.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
mov IVC.16b, BLK2.16b
|
||||
eor BLK0.16b, BLK0.16b, CT1.16b
|
||||
eor BLK1.16b, BLK1.16b, CT2.16b
|
||||
eor BLK2.16b, BLK2.16b, CT3.16b
|
||||
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b}, [OUT]
|
||||
b .Lcfb_aesdec_finish
|
||||
|
||||
.Lcfb_dec_proc_4_blks:
|
||||
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN]
|
||||
mov CT1.16b, IVC.16b
|
||||
mov CT2.16b, BLK0.16b
|
||||
mov CT3.16b, BLK1.16b
|
||||
mov CT4.16b, BLK2.16b
|
||||
AES_ENC_4_BLKS KEY CT1.16b CT2.16b CT3.16b CT4.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
mov IVC.16b, BLK3.16b
|
||||
|
||||
eor BLK0.16b, BLK0.16b, CT1.16b
|
||||
eor BLK1.16b, BLK1.16b, CT2.16b
|
||||
eor BLK2.16b, BLK2.16b, CT3.16b
|
||||
eor BLK3.16b, BLK3.16b, CT4.16b
|
||||
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT]
|
||||
b .Lcfb_aesdec_finish
|
||||
|
||||
.Lcfb_dec_proc_5_blks:
|
||||
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b}, [IN]
|
||||
mov CT1.16b, IVC.16b
|
||||
mov CT2.16b, BLK0.16b
|
||||
mov CT3.16b, BLK1.16b
|
||||
mov CT4.16b, BLK2.16b
|
||||
mov CT5.16b, BLK3.16b
|
||||
|
||||
AES_ENC_5_BLKS KEY CT1.16b CT2.16b CT3.16b CT4.16b CT5.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
mov IVC.16b, BLK4.16b
|
||||
|
||||
eor BLK0.16b, BLK0.16b, CT1.16b
|
||||
eor BLK1.16b, BLK1.16b, CT2.16b
|
||||
eor BLK2.16b, BLK2.16b, CT3.16b
|
||||
eor BLK3.16b, BLK3.16b, CT4.16b
|
||||
eor BLK4.16b, BLK4.16b, CT5.16b
|
||||
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b}, [OUT]
|
||||
b .Lcfb_aesdec_finish
|
||||
.Lcfb_dec_proc_6_blks:
|
||||
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b, BLK5.16b}, [IN]
|
||||
mov CT1.16b, IVC.16b
|
||||
mov CT2.16b, BLK0.16b
|
||||
mov CT3.16b, BLK1.16b
|
||||
mov CT4.16b, BLK2.16b
|
||||
mov CT5.16b, BLK3.16b
|
||||
mov CT6.16b, BLK4.16b
|
||||
|
||||
AES_ENC_6_BLKS KEY CT1.16b CT2.16b CT3.16b CT4.16b CT5.16b CT6.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
mov IVC.16b, BLK5.16b
|
||||
|
||||
eor BLK0.16b, BLK0.16b, CT1.16b
|
||||
eor BLK1.16b, BLK1.16b, CT2.16b
|
||||
eor BLK2.16b, BLK2.16b, CT3.16b
|
||||
eor BLK3.16b, BLK3.16b, CT4.16b
|
||||
eor BLK4.16b, BLK4.16b, CT5.16b
|
||||
eor BLK5.16b, BLK5.16b, CT6.16b
|
||||
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b, BLK5.16b}, [OUT]
|
||||
b .Lcfb_aesdec_finish
|
||||
|
||||
.Lcfb_dec_proc_7_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b, BLK5.16b, BLK6.16b}, [IN]
|
||||
mov CT1.16b, IVC.16b
|
||||
mov CT2.16b, BLK0.16b
|
||||
mov CT3.16b, BLK1.16b
|
||||
mov CT4.16b, BLK2.16b
|
||||
mov CT5.16b, BLK3.16b
|
||||
mov CT6.16b, BLK4.16b
|
||||
mov CT7.16b, BLK5.16b
|
||||
|
||||
AES_ENC_7_BLKS KEY CT1.16b CT2.16b CT3.16b CT4.16b CT5.16b CT6.16b CT7.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
mov IVC.16b, BLK6.16b
|
||||
|
||||
eor BLK0.16b, BLK0.16b, CT1.16b
|
||||
eor BLK1.16b, BLK1.16b, CT2.16b
|
||||
eor BLK2.16b, BLK2.16b, CT3.16b
|
||||
eor BLK3.16b, BLK3.16b, CT4.16b
|
||||
eor BLK4.16b, BLK4.16b, CT5.16b
|
||||
eor BLK5.16b, BLK5.16b, CT6.16b
|
||||
eor BLK6.16b, BLK6.16b, CT7.16b
|
||||
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b, BLK5.16b, BLK6.16b}, [OUT]
|
||||
|
||||
.Lcfb_aesdec_finish:
|
||||
st1 {IVC.16b}, [IV]
|
||||
|
||||
.Lcfb_len_zero:
|
||||
mov x0, #0
|
||||
eor CT1.16b, CT1.16b, CT1.16b
|
||||
eor CT2.16b, CT2.16b, CT2.16b
|
||||
eor CT3.16b, CT3.16b, CT3.16b
|
||||
eor CT4.16b, CT4.16b, CT4.16b
|
||||
eor CT5.16b, CT5.16b, CT5.16b
|
||||
eor CT6.16b, CT6.16b, CT6.16b
|
||||
eor RDK0.16b, RDK0.16b, RDK0.16b
|
||||
eor RDK1.16b, RDK1.16b, RDK1.16b
|
||||
|
||||
.inst 0xd50323bf // autiasp
|
||||
ret
|
||||
.size CRYPT_AES_CFB_Decrypt, .-CRYPT_AES_CFB_Decrypt
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_CRYPTO_AES
|
||||
|
||||
.file "crypt_aes_common_aarch32.S"
|
||||
.code 32
|
||||
.text
|
||||
|
||||
/*
|
||||
* Data initialization
|
||||
* ptr base address
|
||||
*/
|
||||
.macro INIT ptr
|
||||
adr lr, \ptr
|
||||
ldr r12, [r0, #240] // Load rounds.
|
||||
mov r3, #0xff
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Data preprocessing, XOR of plaintext and key (for encryption)
|
||||
* offset Address offset
|
||||
*/
|
||||
.macro PRE_PROCESS_ENC offset
|
||||
sub lr, lr, #\offset // Mix_EncTable's address.
|
||||
sub r12, r12, #1
|
||||
ldr r8, [r0], #16 // Load key.
|
||||
eor r4, r4, r8
|
||||
ldr r9, [r0, #-12]
|
||||
eor r5, r5, r9
|
||||
ldr r10, [r0, #-8]
|
||||
eor r6, r6, r10
|
||||
ldr r11, [r0, #-4]
|
||||
eor r7, r7, r11 // Plaintext XOR key.
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Loop Encryption Process
|
||||
* Excute n - 1 rounds of loop
|
||||
*/
|
||||
.macro LOOP_PROCESS_ENC
|
||||
.Laes_enc_loop:
|
||||
lsr r9, r4, #24 // D
|
||||
and r10, r3, r4, lsr#16 // C
|
||||
ldr r9, [lr, r9, lsl#2] // d
|
||||
and r11, r3, r4, lsr#8 // B
|
||||
ldr r10, [lr, r10, lsl#2] // c
|
||||
and r4, r4, r3 // A
|
||||
ldr r11, [lr, r11, lsl#2] // b
|
||||
lsr r1, r5, #24 // H
|
||||
ldr r4, [lr, r4, lsl#2] // A sbox and mix columns.
|
||||
|
||||
and r2, r3, r5, lsr#16 // G
|
||||
ldr r1, [lr, r1, lsl#2]
|
||||
and r8, r3, r5, lsr#8 // F
|
||||
ldr r2, [lr, r2, lsl#2]
|
||||
and r5, r5, r3 // E
|
||||
ldr r8, [lr, r8, lsl#2]
|
||||
eor r10, r10, r1, ror#24 // c ^ h
|
||||
ldr r5, [lr, r5, lsl#2] // Sbox and mix columns.
|
||||
eor r4, r4, r8, ror#24 // a ^ f
|
||||
eor r11, r11, r2, ror#24 // b ^ g
|
||||
lsr r1, r6, #24 // L
|
||||
eor r5, r5, r9, ror#8 // e ^ d
|
||||
|
||||
and r8, r3, r6, lsr#16 // K
|
||||
subs r12, r12, #1 // Rounds counter.
|
||||
and r9, r3, r6, lsr#8 // J
|
||||
ldr r1, [lr, r1, lsl#2]
|
||||
ldr r8, [lr, r8, lsl#2]
|
||||
and r6, r6, r3 // I
|
||||
eor r4, r4, r8, ror#16 // a ^ f ^ k
|
||||
ldr r9, [lr, r9, lsl#2]
|
||||
ldr r6, [lr, r6, lsl#2] // Sbox and mix columns.
|
||||
eor r5, r5, r9, ror#24 // e ^ j ^ d
|
||||
lsr r8, r7, #24 // P
|
||||
eor r11, r11, r1, ror#16 // b ^ g ^ l
|
||||
and r9, r3, r7, lsr#16 // O
|
||||
ldr r8, [lr, r8, lsl#2]
|
||||
eor r6, r6, r10, ror#16 // i ^ c ^ h
|
||||
|
||||
and r10, r3, r7, lsr#8 // N
|
||||
ldr r9, [lr, r9, lsl#2]
|
||||
and r7, r7, r3 // M
|
||||
ldr r10, [lr, r10, lsl#2]
|
||||
eor r4, r4, r8, ror#8 // a ^ f ^ k ^ p
|
||||
ldr r7, [lr, r7, lsl#2] // Sbox and mix columns.
|
||||
eor r5, r5, r9, ror#16 // e ^ j ^ o ^ d
|
||||
ldr r8, [r0], #16 // Load key.
|
||||
eor r6, r6, r10, ror#24 // i ^ n ^ c ^ h
|
||||
ldr r9, [r0, #-12]
|
||||
eor r7, r7, r11, ror#24 // m ^ b ^ g ^ l
|
||||
|
||||
eor r4, r4, r8
|
||||
ldr r10, [r0, #-8]
|
||||
eor r5, r5, r9
|
||||
ldr r11, [r0, #-4]
|
||||
eor r6, r6, r10
|
||||
eor r7, r7, r11 // Plaintext XOR key.
|
||||
bgt .Laes_enc_loop
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Last round of encryption
|
||||
* (n - 1) + 1 = n required rounds of encryption completed
|
||||
*/
|
||||
.macro LAST_PROCESS_ENC
|
||||
lsr r9, r4, #24 // D
|
||||
add lr, lr, #0x400 // Add 1024 to Sbox.
|
||||
and r10, r3, r4, lsr#16 // C
|
||||
ldrb r9, [lr, r9]
|
||||
and r11, r3, r4, lsr#8 // B
|
||||
ldrb r10, [lr, r10]
|
||||
and r4, r4, r3 // A
|
||||
ldrb r11, [lr, r11]
|
||||
lsr r1, r5, #24 // H
|
||||
ldrb r4, [lr, r4] // Sbox
|
||||
|
||||
and r2, r3, r5, lsr#16 // G
|
||||
ldrb r1, [lr, r1]
|
||||
and r8, r3, r5, lsr#8 // F
|
||||
ldrb r2, [lr, r2]
|
||||
and r5, r5, r3 // E
|
||||
ldrb r8, [lr, r8]
|
||||
eor r10, r10, r1, lsl#8 // HC
|
||||
ldrb r5, [lr, r5] // Sbox
|
||||
eor r4, r4, r8, lsl#8 // 00FA
|
||||
eor r11, r11, r2, lsl#8 // GB
|
||||
lsr r1, r6, #24 // L
|
||||
eor r5, r5, r9, lsl#24 // D00E
|
||||
|
||||
and r8, r3, r6, lsr#16 // K
|
||||
ldrb r1, [lr, r1]
|
||||
and r9, r3, r6, lsr#8 // J
|
||||
ldrb r8, [lr, r8]
|
||||
and r6, r6, r3 // I
|
||||
ldrb r9, [lr, r9]
|
||||
eor r4, r4, r8, lsl#16 // 0KFA
|
||||
ldrb r6, [lr, r6] // sbox
|
||||
eor r5, r5, r9, lsl#8 // D0JE
|
||||
eor r6, r6, r10, lsl#16 // HC0I
|
||||
lsr r8, r7, #24 // P
|
||||
eor r11, r11, r1, lsl#16 // LGB
|
||||
|
||||
and r9, r3, r7, lsr#16 // O
|
||||
ldrb r8, [lr, r8]
|
||||
and r10, r3, r7, lsr#8 // N
|
||||
ldrb r9, [lr, r9]
|
||||
and r7, r7, r3 // M
|
||||
ldrb r10, [lr, r10]
|
||||
eor r4, r4, r8, lsl#24 // PKFA
|
||||
ldrb r7, [lr, r7] // sbox
|
||||
eor r5, r5, r9, lsl#16 // DOJE
|
||||
eor r6, r6, r10, lsl#8 // HCNI
|
||||
ldr r8, [r0], #16 // load key
|
||||
eor r7, r7, r11, lsl#8 // LGBM
|
||||
ldr r9, [r0, #-12]
|
||||
|
||||
eor r4, r4, r8
|
||||
ldr r10, [r0, #-8]
|
||||
eor r5, r5, r9
|
||||
ldr r11, [r0, #-4]
|
||||
eor r6, r6, r10
|
||||
eor r7, r7, r11 // Plaintext XOR key.
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Data preprocessing, XOR between plaintext and key (for decryption)
|
||||
* offset Address offset
|
||||
*/
|
||||
.macro PRE_PROCESS_DEC offset
|
||||
sub lr, lr, #\offset // Mix_EncTable's address.
|
||||
ldr r8, [r0], #16 // Load key.
|
||||
sub r12, r12, #1
|
||||
ldr r9, [r0, #-12]
|
||||
eor r4, r4, r8
|
||||
ldr r10, [r0, #-8]
|
||||
eor r5, r5, r9
|
||||
ldr r11, [r0, #-4]
|
||||
eor r6, r6, r10
|
||||
eor r7, r7, r11 // Plaintext XOR key.
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Decryption loop processing flow
|
||||
* n - 1 round of decryption
|
||||
*/
|
||||
.macro LOOP_PROCESS_DEC
|
||||
.Laes_dec_loop:
|
||||
and r10, r3, r4, lsr#16 // C
|
||||
lsr r11, r4, #24 // D
|
||||
ldr r10, [lr, r10, lsl#2]
|
||||
and r9, r3, r4, lsr#8 // B
|
||||
ldr r11, [lr, r11, lsl#2]
|
||||
lsl r4, r4, #24 // A
|
||||
ldr r9, [lr, r9, lsl#2]
|
||||
lsr r8, r5, #24 // H
|
||||
ldr r4, [lr, r4, lsr#22] // (inv)sbox and mix columns
|
||||
|
||||
and r2, r3, r5, lsr#16 // G
|
||||
ldr r8, [lr, r8, lsl#2]
|
||||
and r1, r3, r5, lsr#8 // F
|
||||
ldr r2, [lr, r2, lsl#2]
|
||||
and r5, r3, r5 // E
|
||||
ldr r1, [lr, r1, lsl#2]
|
||||
eor r4, r4, r8, ror#8 // a ^ h
|
||||
ldr r5, [lr, r5, lsl#2] // (inv)sbox and mix columns
|
||||
eor r11, r11, r2, ror#8 // g ^ d
|
||||
and r8, r3, r6, lsr#16 // K
|
||||
eor r10, r10, r1, ror#8 // f ^ c
|
||||
eor r5, r5, r9, ror#24 // e ^ b
|
||||
lsr r9, r6, #24 // L
|
||||
|
||||
and r1, r3, r6, lsr#8 // J
|
||||
ldr r9, [lr, r9, lsl#2]
|
||||
and r6, r3, r6 // I
|
||||
ldr r8, [lr, r8, lsl#2]
|
||||
eor r5, r5, r9, ror#8 // e ^ b ^ l
|
||||
ldr r1, [lr, r1, lsl#2]
|
||||
eor r4, r4, r8, ror#16 // a ^ k ^ h
|
||||
ldr r6, [lr, r6, lsl#2] // (inv)sbox and mix columns
|
||||
eor r11, r11, r1, ror#16 // j ^ g ^ d
|
||||
and r9, r3, r7, lsr#16 // O
|
||||
eor r6, r6, r10, ror#16 // i ^ f ^ c
|
||||
|
||||
and r8, r3, r7, lsr#8 // N
|
||||
ldr r9, [lr, r9, lsl#2]
|
||||
lsr r10, r7, #24 // P
|
||||
ldr r8, [lr, r8, lsl#2]
|
||||
and r7, r3, r7 // M
|
||||
ldr r10, [lr, r10, lsl#2]
|
||||
eor r5, r5, r9, ror#16 // e ^ b ^ o ^ l
|
||||
ldr r7, [lr, r7, lsl#2] // (inv)sbox and mix columns
|
||||
eor r6, r6, r10, ror#8 // i ^ f ^ c ^ p
|
||||
subs r12, r12, #1 // Rounds counter.
|
||||
eor r4, r4, r8, ror#24 // a ^ n ^ k ^ h
|
||||
ldr r8, [r0], #16 // load key
|
||||
eor r7, r7, r11, ror#8 // m ^ j ^ g ^ d
|
||||
|
||||
ldr r9, [r0, #-12]
|
||||
eor r4, r4, r8
|
||||
ldr r10, [r0, #-8]
|
||||
eor r5, r5, r9
|
||||
ldr r11, [r0, #-4]
|
||||
eor r6, r6, r10
|
||||
eor r7, r7, r11 // Plaintext XOR key.
|
||||
bgt .Laes_dec_loop
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Last round of decryption
|
||||
* (n - 1) + 1 = n required n rounds of decryption complete
|
||||
*/
|
||||
.macro LAST_PROCESS_DEC
|
||||
add lr, lr, #0x400 // Add 1024 to Sbox.
|
||||
lsr r11, r4, #24 // D
|
||||
and r10, r3, r4, lsr#16 // C
|
||||
ldrb r11, [lr, r11]
|
||||
and r9, r3, r4, lsr#8 // B
|
||||
ldrb r10, [lr, r10]
|
||||
and r4, r4, r3 // A
|
||||
ldrb r9, [lr, r9]
|
||||
lsr r8, r5, #24 // H
|
||||
ldrb r4, [lr, r4] // (inv)sbox
|
||||
|
||||
and r2, r3, r5, lsr#16 // G
|
||||
ldrb r8, [lr, r8]
|
||||
and r1, r3, r5, lsr#8 // F
|
||||
ldrb r2, [lr, r2]
|
||||
and r5, r5, r3 // E
|
||||
ldrb r1, [lr, r1]
|
||||
eor r4, r4, r8, lsl#24 // H00A
|
||||
ldrb r5, [lr, r5] // (inv)sbox
|
||||
eor r10, r1, r10, lsl#8 // CF
|
||||
eor r5, r5, r9, lsl#8 // 00BE
|
||||
and r8, r3, r6, lsr#16 // K
|
||||
eor r11, r2, r11, lsl#8 // DG
|
||||
|
||||
lsr r9, r6, #24 // L
|
||||
and r1, r3, r6, lsr#8 // J
|
||||
ldrb r9, [lr, r9]
|
||||
and r6, r6, r3 // I
|
||||
ldrb r8, [lr, r8]
|
||||
eor r4, r4, r8, lsl#16 // HK0A
|
||||
ldrb r1, [lr, r1]
|
||||
eor r5, r5, r9, lsl#24 // L0BE
|
||||
ldrb r6, [lr, r6] // (inv)sbox
|
||||
eor r11, r1, r11, lsl#8 // DGJ
|
||||
and r9, r3, r7, lsr#16 // O
|
||||
eor r6, r6, r10, lsl#8 // CFI
|
||||
|
||||
lsr r10, r7, #24 // P
|
||||
and r8, r3, r7, lsr#8 // N
|
||||
ldrb r10, [lr, r10]
|
||||
and r7, r7, r3 // M
|
||||
ldrb r9, [lr, r9]
|
||||
eor r5, r5, r9, lsl#16 // LOBE
|
||||
ldrb r8, [lr, r8]
|
||||
eor r4, r4, r8, lsl#8 // HKNA
|
||||
ldrb r7, [lr, r7] // (inv)sbox
|
||||
eor r6, r6, r10, lsl#24 // PCFI
|
||||
ldr r8, [r0], #16 // load key
|
||||
eor r7, r7, r11, lsl#8 // DGJM
|
||||
|
||||
ldr r9, [r0, #-12]
|
||||
eor r4, r4, r8
|
||||
ldr r10, [r0, #-8]
|
||||
eor r5, r5, r9
|
||||
ldr r11, [r0, #-4]
|
||||
eor r6, r6, r10
|
||||
eor r7, r7, r11 // Plaintext XOR key.
|
||||
.endm
|
||||
|
||||
.macro RESULT ptr
|
||||
str r4, [\ptr]
|
||||
str r5, [\ptr, #4]
|
||||
str r6, [\ptr, #8]
|
||||
str r7, [\ptr, #12] // Return result.
|
||||
eor r0, r0, r0 // Return CRYPT_SUCCESS.
|
||||
.endm
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_CTR)
|
||||
|
||||
#include "crypt_aes_macro_armv8.s"
|
||||
|
||||
.file "crypt_aes_ctr_armv8.S"
|
||||
.text
|
||||
.arch armv8-a+crypto
|
||||
|
||||
.align 5
|
||||
|
||||
KEY .req x0
|
||||
IN .req x1
|
||||
OUT .req x2
|
||||
LEN .req x3
|
||||
IV .req x4
|
||||
|
||||
LTMP .req x12
|
||||
CTMP .req v27
|
||||
|
||||
BLK0 .req v0
|
||||
BLK1 .req v1
|
||||
BLK2 .req v2
|
||||
BLK3 .req v3
|
||||
BLK4 .req v4
|
||||
BLK5 .req v5
|
||||
BLK6 .req v6
|
||||
BLK7 .req v7
|
||||
|
||||
CTR0 .req v19
|
||||
CTR1 .req v20
|
||||
CTR2 .req v21
|
||||
CTR3 .req v22
|
||||
CTR4 .req v23
|
||||
CTR5 .req v24
|
||||
CTR6 .req v25
|
||||
CTR7 .req v26
|
||||
|
||||
RDK0 .req v17
|
||||
RDK1 .req v18
|
||||
ROUNDS .req w6
|
||||
|
||||
/* ctr + 1 */
|
||||
.macro ADDCTR ctr
|
||||
#ifndef HITLS_BIG_ENDIAN
|
||||
add w11, w11, #1
|
||||
rev w9, w11
|
||||
mov \ctr, w9
|
||||
#else
|
||||
rev w11, w11
|
||||
add w11, w11, #1
|
||||
rev w11, w11
|
||||
mov \ctr, w11
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Vn - V0 ~ V31
|
||||
* 8bytes - Vn.8B Vn.4H Vn.2S Vn.1D
|
||||
* 16bytes - Vn.16B Vn.8H Vn.4S Vn.2D
|
||||
*/
|
||||
|
||||
/*
|
||||
* int32_t CRYPT_AES_CTR_Encrypt(const CRYPT_AES_Key *ctx,
|
||||
* const uint8_t *in,
|
||||
* uint8_t *out,
|
||||
* uint32_t len,
|
||||
* uint8_t *iv);
|
||||
*/
|
||||
|
||||
.globl CRYPT_AES_CTR_Encrypt
|
||||
.type CRYPT_AES_CTR_Encrypt, %function
|
||||
CRYPT_AES_CTR_Encrypt:
|
||||
.inst 0xd503233f // Paciasp.
|
||||
ld1 {CTR0.16b}, [IV] // Reads the IV.
|
||||
mov CTMP.16b, CTR0.16b
|
||||
mov w11, CTR0.s[3]
|
||||
#ifndef HITLS_BIG_ENDIAN
|
||||
rev w11, w11
|
||||
#endif
|
||||
mov LTMP, LEN
|
||||
|
||||
.Lctr_aesenc_start:
|
||||
cmp LTMP, #64
|
||||
b.ge .Lctr_enc_above_equal_4_blks
|
||||
cmp LTMP, #32
|
||||
b.ge .Lctr_enc_above_equal_2_blks
|
||||
cmp LTMP, #0
|
||||
b.eq .Lctr_len_zero
|
||||
b .Lctr_enc_proc_1_blk
|
||||
|
||||
.Lctr_enc_above_equal_2_blks:
|
||||
cmp LTMP, #48
|
||||
b.lt .Lctr_enc_proc_2_blks
|
||||
b .Lctr_enc_proc_3_blks
|
||||
|
||||
.Lctr_enc_above_equal_4_blks:
|
||||
cmp LTMP, #96
|
||||
b.ge .Lctr_enc_above_equal_6_blks
|
||||
cmp LTMP, #80
|
||||
b.lt .Lctr_enc_proc_4_blks
|
||||
b .Lctr_enc_proc_5_blks
|
||||
|
||||
.Lctr_enc_above_equal_6_blks:
|
||||
cmp LTMP, #112
|
||||
b.lt .Lctr_enc_proc_6_blks
|
||||
cmp LTMP, #128
|
||||
b.lt .Lctr_enc_proc_7_blks
|
||||
|
||||
.Lctr_enc_proc_8_blks:
|
||||
|
||||
/* When the length is greater than or equal to 128, eight blocks loop is used. */
|
||||
.Lctr_aesenc_8_blks_loop:
|
||||
|
||||
/* Calculate eight CTRs. */
|
||||
mov CTR1.16b, CTMP.16b
|
||||
mov CTR2.16b, CTMP.16b
|
||||
mov CTR3.16b, CTMP.16b
|
||||
mov CTR4.16b, CTMP.16b
|
||||
mov CTR5.16b, CTMP.16b
|
||||
mov CTR6.16b, CTMP.16b
|
||||
mov CTR7.16b, CTMP.16b
|
||||
|
||||
ADDCTR CTR1.s[3]
|
||||
ADDCTR CTR2.s[3]
|
||||
ADDCTR CTR3.s[3]
|
||||
ADDCTR CTR4.s[3]
|
||||
ADDCTR CTR5.s[3]
|
||||
ADDCTR CTR6.s[3]
|
||||
ADDCTR CTR7.s[3]
|
||||
|
||||
mov x14, KEY // Prevent the key from being changed.
|
||||
AES_ENC_8_BLKS x14 CTR0.16b CTR1.16b CTR2.16b CTR3.16b CTR4.16b \
|
||||
CTR5.16b CTR6.16b CTR7.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b}, [IN], #64
|
||||
|
||||
eor BLK0.16b, BLK0.16b, CTR0.16b
|
||||
eor BLK1.16b, BLK1.16b, CTR1.16b
|
||||
eor BLK2.16b, BLK2.16b, CTR2.16b
|
||||
eor BLK3.16b, BLK3.16b, CTR3.16b
|
||||
eor BLK4.16b, BLK4.16b, CTR4.16b
|
||||
eor BLK5.16b, BLK5.16b, CTR5.16b
|
||||
eor BLK6.16b, BLK6.16b, CTR6.16b
|
||||
eor BLK7.16b, BLK7.16b, CTR7.16b
|
||||
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b}, [OUT], #64
|
||||
|
||||
sub LTMP, LTMP, #128
|
||||
cmp LTMP, #0
|
||||
b.eq .Lctr_aesenc_finish
|
||||
|
||||
ADDCTR CTMP.s[3]
|
||||
mov CTR0.16b, CTMP.16b
|
||||
|
||||
cmp LTMP, #128
|
||||
b.lt .Lctr_aesenc_start
|
||||
b .Lctr_aesenc_8_blks_loop
|
||||
|
||||
.Lctr_enc_proc_1_blk:
|
||||
|
||||
AES_ENC_1_BLK KEY CTR0.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
ld1 {BLK0.16b}, [IN]
|
||||
eor BLK0.16b, CTR0.16b, BLK0.16b
|
||||
st1 {BLK0.16b}, [OUT]
|
||||
b .Lctr_aesenc_finish
|
||||
|
||||
.Lctr_enc_proc_2_blks:
|
||||
|
||||
mov CTR1.16b, CTMP.16b
|
||||
ADDCTR CTR1.s[3]
|
||||
|
||||
AES_ENC_2_BLKS KEY CTR0.16b CTR1.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
ld1 {BLK0.16b, BLK1.16b}, [IN]
|
||||
|
||||
eor BLK0.16b, CTR0.16b, BLK0.16b
|
||||
eor BLK1.16b, CTR1.16b, BLK1.16b
|
||||
|
||||
st1 {BLK0.16b, BLK1.16b}, [OUT]
|
||||
b .Lctr_aesenc_finish
|
||||
|
||||
.Lctr_enc_proc_3_blks:
|
||||
|
||||
mov CTR1.16b, CTMP.16b
|
||||
mov CTR2.16b, CTMP.16b
|
||||
|
||||
ADDCTR CTR1.s[3]
|
||||
ADDCTR CTR2.s[3]
|
||||
|
||||
AES_ENC_3_BLKS KEY CTR0.16b CTR1.16b CTR2.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b}, [IN]
|
||||
|
||||
eor BLK0.16b, BLK0.16b, CTR0.16b
|
||||
eor BLK1.16b, BLK1.16b, CTR1.16b
|
||||
eor BLK2.16b, BLK2.16b, CTR2.16b
|
||||
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b}, [OUT]
|
||||
b .Lctr_aesenc_finish
|
||||
|
||||
.Lctr_enc_proc_4_blks:
|
||||
|
||||
mov CTR1.16b, CTMP.16b
|
||||
mov CTR2.16b, CTMP.16b
|
||||
mov CTR3.16b, CTMP.16b
|
||||
|
||||
ADDCTR CTR1.s[3]
|
||||
ADDCTR CTR2.s[3]
|
||||
ADDCTR CTR3.s[3]
|
||||
|
||||
AES_ENC_4_BLKS KEY CTR0.16b CTR1.16b CTR2.16b CTR3.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN]
|
||||
|
||||
eor BLK0.16b, BLK0.16b, CTR0.16b
|
||||
eor BLK1.16b, BLK1.16b, CTR1.16b
|
||||
eor BLK2.16b, BLK2.16b, CTR2.16b
|
||||
eor BLK3.16b, BLK3.16b, CTR3.16b
|
||||
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT]
|
||||
b .Lctr_aesenc_finish
|
||||
|
||||
.Lctr_enc_proc_5_blks:
|
||||
|
||||
mov CTR1.16b, CTMP.16b
|
||||
mov CTR2.16b, CTMP.16b
|
||||
mov CTR3.16b, CTMP.16b
|
||||
mov CTR4.16b, CTMP.16b
|
||||
|
||||
ADDCTR CTR1.s[3]
|
||||
ADDCTR CTR2.s[3]
|
||||
ADDCTR CTR3.s[3]
|
||||
ADDCTR CTR4.s[3]
|
||||
|
||||
AES_ENC_5_BLKS KEY CTR0.16b CTR1.16b CTR2.16b CTR3.16b CTR4.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b}, [IN]
|
||||
|
||||
eor BLK0.16b, BLK0.16b, CTR0.16b
|
||||
eor BLK1.16b, BLK1.16b, CTR1.16b
|
||||
eor BLK2.16b, BLK2.16b, CTR2.16b
|
||||
eor BLK3.16b, BLK3.16b, CTR3.16b
|
||||
eor BLK4.16b, BLK4.16b, CTR4.16b
|
||||
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b}, [OUT]
|
||||
b .Lctr_aesenc_finish
|
||||
|
||||
.Lctr_enc_proc_6_blks:
|
||||
|
||||
mov CTR1.16b, CTMP.16b
|
||||
mov CTR2.16b, CTMP.16b
|
||||
mov CTR3.16b, CTMP.16b
|
||||
mov CTR4.16b, CTMP.16b
|
||||
mov CTR5.16b, CTMP.16b
|
||||
|
||||
ADDCTR CTR1.s[3]
|
||||
ADDCTR CTR2.s[3]
|
||||
ADDCTR CTR3.s[3]
|
||||
ADDCTR CTR4.s[3]
|
||||
ADDCTR CTR5.s[3]
|
||||
|
||||
AES_ENC_6_BLKS KEY CTR0.16b CTR1.16b CTR2.16b CTR3.16b CTR4.16b \
|
||||
CTR5.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b, BLK5.16b}, [IN]
|
||||
|
||||
eor BLK0.16b, BLK0.16b, CTR0.16b
|
||||
eor BLK1.16b, BLK1.16b, CTR1.16b
|
||||
eor BLK2.16b, BLK2.16b, CTR2.16b
|
||||
eor BLK3.16b, BLK3.16b, CTR3.16b
|
||||
eor BLK4.16b, BLK4.16b, CTR4.16b
|
||||
eor BLK5.16b, BLK5.16b, CTR5.16b
|
||||
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b, BLK5.16b}, [OUT]
|
||||
b .Lctr_aesenc_finish
|
||||
|
||||
.Lctr_enc_proc_7_blks:
|
||||
|
||||
mov CTR1.16b, CTMP.16b
|
||||
mov CTR2.16b, CTMP.16b
|
||||
mov CTR3.16b, CTMP.16b
|
||||
mov CTR4.16b, CTMP.16b
|
||||
mov CTR5.16b, CTMP.16b
|
||||
mov CTR6.16b, CTMP.16b
|
||||
|
||||
ADDCTR CTR1.s[3]
|
||||
ADDCTR CTR2.s[3]
|
||||
ADDCTR CTR3.s[3]
|
||||
ADDCTR CTR4.s[3]
|
||||
ADDCTR CTR5.s[3]
|
||||
ADDCTR CTR6.s[3]
|
||||
|
||||
AES_ENC_7_BLKS KEY CTR0.16b CTR1.16b CTR2.16b CTR3.16b CTR4.16b \
|
||||
CTR5.16b CTR6.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b, BLK5.16b, BLK6.16b}, [IN]
|
||||
|
||||
eor BLK0.16b, BLK0.16b, CTR0.16b
|
||||
eor BLK1.16b, BLK1.16b, CTR1.16b
|
||||
eor BLK2.16b, BLK2.16b, CTR2.16b
|
||||
eor BLK3.16b, BLK3.16b, CTR3.16b
|
||||
eor BLK4.16b, BLK4.16b, CTR4.16b
|
||||
eor BLK5.16b, BLK5.16b, CTR5.16b
|
||||
eor BLK6.16b, BLK6.16b, CTR6.16b
|
||||
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b, BLK5.16b, BLK6.16b}, [OUT]
|
||||
|
||||
.Lctr_aesenc_finish:
|
||||
ADDCTR CTMP.s[3] // Fill CTR0 for the next round.
|
||||
st1 {CTMP.16b}, [IV]
|
||||
|
||||
.Lctr_len_zero:
|
||||
mov x0, #0
|
||||
eor CTR0.16b, CTR0.16b, CTR0.16b
|
||||
eor CTR1.16b, CTR1.16b, CTR1.16b
|
||||
eor CTR2.16b, CTR2.16b, CTR2.16b
|
||||
eor CTR3.16b, CTR3.16b, CTR3.16b
|
||||
eor CTR4.16b, CTR4.16b, CTR4.16b
|
||||
eor CTR5.16b, CTR5.16b, CTR5.16b
|
||||
eor CTR6.16b, CTR6.16b, CTR6.16b
|
||||
eor CTR7.16b, CTR7.16b, CTR7.16b
|
||||
eor RDK0.16b, RDK0.16b, RDK0.16b
|
||||
eor RDK1.16b, RDK1.16b, RDK1.16b
|
||||
|
||||
.inst 0xd50323bf // Autiasp.
|
||||
ret
|
||||
.size CRYPT_AES_CTR_Encrypt, .-CRYPT_AES_CTR_Encrypt
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,588 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_CTR)
|
||||
|
||||
.file "crypt_aes_ctr_x86_64.S"
|
||||
.text
|
||||
|
||||
.set KEY, %rdi
|
||||
.set INPUT, %rsi
|
||||
.set OUTPUT, %rdx
|
||||
.set LEN, %ecx
|
||||
.set CTR_IV, %r8
|
||||
|
||||
.set RDK, %xmm0
|
||||
.set RDK2, %xmm1
|
||||
.set KTMP, %r13
|
||||
.set ROUNDS, %eax
|
||||
.set RET, %eax
|
||||
|
||||
.set IV0, %xmm2
|
||||
.set IV1, %xmm3
|
||||
.set IV2, %xmm4
|
||||
.set IV3, %xmm5
|
||||
.set IV4, %xmm6
|
||||
.set IV5, %xmm7
|
||||
.set IV6, %xmm8
|
||||
.set IV7, %xmm9
|
||||
.set BLK0, %xmm10
|
||||
.set BLK1, %xmm11
|
||||
.set BLK2, %xmm12
|
||||
.set BLK3, %xmm13
|
||||
.set BLK4, %xmm14
|
||||
.set BLK5, %xmm15
|
||||
|
||||
/**
|
||||
* Macro description: Eight IVs are encrypted.
|
||||
* Input register:
|
||||
* Key: Round key.
|
||||
* block0-7: Encrypted IV.
|
||||
* Modify the register: block0-7.
|
||||
* Output register:
|
||||
* block0-7: IV after a round of encryption.
|
||||
*/
|
||||
.macro ONE_ENC key block0 block1 block2 block3 block4 block5 block6 block7
|
||||
aesenc \key, \block0
|
||||
aesenc \key, \block1
|
||||
aesenc \key, \block2
|
||||
aesenc \key, \block3
|
||||
aesenc \key, \block4
|
||||
aesenc \key, \block5
|
||||
aesenc \key, \block6
|
||||
aesenc \key, \block7
|
||||
.endm
|
||||
|
||||
/**
|
||||
* Macro description: Obtains a new ctr and XORs it with the round key.
|
||||
* input register:
|
||||
* ctr32:Initialization vector.
|
||||
* offset:Offset.
|
||||
* temp:32-bit CTR temporary register.
|
||||
* key32:32-bit round key.
|
||||
* addrOffset:push stack address offset.
|
||||
* addr:push stack address.
|
||||
* Modify the register: Temp.
|
||||
*/
|
||||
.macro XOR_KEY ctr32 offset temp key32 addrOffset addr
|
||||
leal \offset(\ctr32), \temp // XOR 32-bit ctr and key, push into the stack
|
||||
bswapl \temp
|
||||
xorl \key32, \temp
|
||||
movl \temp, \addrOffset+12(\addr)
|
||||
.endm
|
||||
|
||||
/**
|
||||
* Macro description: Obtain the round key, encrypt the IV, obtain the next round of ctr, and XOR the round key.
|
||||
* Input register:
|
||||
* Key: pointer to the key.
|
||||
* Offset: round key offset.
|
||||
* Temp: Temporary register for the round key.
|
||||
* Ctr32: initialization vector.
|
||||
* Offset2: Ctr offset.
|
||||
* Temp2: 32-bit CTR temporary register.
|
||||
* Key32: 32-bit round key.
|
||||
* AddrOffset: Offest of entering the stack.
|
||||
* Addr: Address for entering the stack.
|
||||
* Modify register: Temp temp2 IV0-7.
|
||||
* Output register:
|
||||
* IV0-7: IV after a round of encryption.
|
||||
*/
|
||||
.macro ONE_ENC_XOR_KEY key offset temp ctr32 offset2 temp2 key32 addrOffset addr
|
||||
vmovdqu \offset(\key), \temp
|
||||
aesenc \temp, IV0
|
||||
leal \offset2(\ctr32), \temp2 // XOR 32-bit ctr and key, push stack.
|
||||
aesenc \temp, IV1
|
||||
bswapl \temp2
|
||||
aesenc \temp, IV2
|
||||
aesenc \temp, IV3
|
||||
xorl \key32, \temp2
|
||||
aesenc \temp, IV4
|
||||
aesenc \temp, IV5
|
||||
movl \temp2, \addrOffset+12(\addr)
|
||||
aesenc \temp, IV6
|
||||
aesenc \temp, IV7
|
||||
|
||||
.endm
|
||||
|
||||
/**
|
||||
* Macro description: Update the in and out pointer offsets and the remaining length of len.
|
||||
* Input register:
|
||||
* Input:pointer to the input memory.
|
||||
* Output:pointer to the output memory.
|
||||
* Len:remaining data length.
|
||||
* Offset:indicates the offset.
|
||||
* Modify the register: Input output len.
|
||||
* Output register:
|
||||
* Input output len
|
||||
*/
|
||||
.macro UPDATE_DATA input output len offset
|
||||
leaq \offset(\input), \input
|
||||
leaq \offset(\output), \output
|
||||
subl $\offset, \len
|
||||
.endm
|
||||
|
||||
/**
|
||||
* Function description:Sets the AES encrypted assembly acceleration API, ctr mode.
|
||||
* Function prototype:int32_t CRYPT_AES_CTR_Encrypt(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out,
|
||||
* uint32_t len, uint8_t *iv);
|
||||
* Input register:
|
||||
* rdi:Pointer to the input key structure.
|
||||
* rsi:Points to the 128-bit input data.
|
||||
* rdx:Points to the 128-bit output data.
|
||||
* rcx:Length of the data block, that is, 16 bytes.
|
||||
* r8: 16-byte initialization vector.
|
||||
* Change register:xmm1, xmm3, xmm4, xmm5, xmm6, xmm10, xmm11, xmm12, xmm13.
|
||||
* Output register:rdx, r8.
|
||||
*/
|
||||
.globl CRYPT_AES_CTR_Encrypt
|
||||
.type CRYPT_AES_CTR_Encrypt, @function
|
||||
CRYPT_AES_CTR_Encrypt:
|
||||
.cfi_startproc
|
||||
pushq %r12
|
||||
pushq %r13
|
||||
pushq %r14
|
||||
mov %rsp, %r12
|
||||
subq $128, %rsp // Declare for 128-byte stack space.
|
||||
andq $-16, %rsp
|
||||
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (CTR_IV), RDK, IV0
|
||||
vmovdqa IV0, 0(%rsp)
|
||||
vmovdqa IV0, 16(%rsp)
|
||||
vmovdqa IV0, 32(%rsp)
|
||||
vmovdqa IV0, 48(%rsp)
|
||||
vmovdqa IV0, 64(%rsp)
|
||||
vmovdqa IV0, 80(%rsp)
|
||||
vmovdqa IV0, 96(%rsp)
|
||||
vmovdqa IV0, 112(%rsp)
|
||||
|
||||
movl 12(CTR_IV), %r11d // Read 32-bit ctr.
|
||||
movl 12(KEY), %r9d // Read 32-bit key.
|
||||
bswap %r11d
|
||||
|
||||
mov LEN, %r14d
|
||||
shr $4, %r14d
|
||||
and $7, %r14d
|
||||
cmp $1, %r14d
|
||||
je .Lctr_enc_proc_1_blk
|
||||
cmp $2, %r14d
|
||||
je .Lctr_enc_proc_2_blk
|
||||
cmp $3, %r14d
|
||||
je .Lctr_enc_proc_3_blk
|
||||
cmp $4, %r14d
|
||||
je .Lctr_enc_proc_4_blk
|
||||
cmp $5, %r14d
|
||||
je .Lctr_enc_proc_5_blk
|
||||
cmp $6, %r14d
|
||||
je .Lctr_enc_proc_6_blk
|
||||
cmp $7, %r14d
|
||||
je .Lctr_enc_proc_7_blk
|
||||
|
||||
.Lctr_enc_proc_8_blk:
|
||||
cmp $0, LEN
|
||||
je .Lctr_aesenc_finish
|
||||
XOR_KEY %r11d, 0, %r10d, %r9d, 0, %rsp
|
||||
XOR_KEY %r11d, 1, %r10d, %r9d, 16, %rsp
|
||||
XOR_KEY %r11d, 2, %r10d, %r9d, 32, %rsp
|
||||
XOR_KEY %r11d, 3, %r10d, %r9d, 48, %rsp
|
||||
XOR_KEY %r11d, 4, %r10d, %r9d, 64, %rsp
|
||||
XOR_KEY %r11d, 5, %r10d, %r9d, 80, %rsp
|
||||
XOR_KEY %r11d, 6, %r10d, %r9d, 96, %rsp
|
||||
XOR_KEY %r11d, 7, %r10d, %r9d, 112, %rsp
|
||||
vmovdqa (%rsp), IV0
|
||||
vmovdqa 16(%rsp), IV1
|
||||
vmovdqa 32(%rsp), IV2
|
||||
vmovdqa 48(%rsp), IV3
|
||||
vmovdqa 64(%rsp), IV4
|
||||
vmovdqa 80(%rsp), IV5
|
||||
vmovdqa 96(%rsp), IV6
|
||||
vmovdqa 112(%rsp), IV7
|
||||
.align 16
|
||||
.Lctr_aesenc_8_blks_enc_loop:
|
||||
addl $8, %r11d // ctr+8
|
||||
movl 240(KEY), ROUNDS
|
||||
ONE_ENC_XOR_KEY KEY, 16, RDK2, %r11d, 0, %r10d, %r9d, 0, %rsp // Round 1 encryption
|
||||
ONE_ENC_XOR_KEY KEY, 32, RDK2, %r11d, 1, %r10d, %r9d, 16, %rsp // Round 2 encryption
|
||||
ONE_ENC_XOR_KEY KEY, 48, RDK2, %r11d, 2, %r10d, %r9d, 32, %rsp // Round 3 encryption
|
||||
ONE_ENC_XOR_KEY KEY, 64, RDK2, %r11d, 3, %r10d, %r9d, 48, %rsp // Round 4 encryption
|
||||
ONE_ENC_XOR_KEY KEY, 80, RDK2, %r11d, 4, %r10d, %r9d, 64, %rsp // Round 5 encryption
|
||||
ONE_ENC_XOR_KEY KEY, 96, RDK2, %r11d, 5, %r10d, %r9d, 80, %rsp // Round 6 encryption
|
||||
ONE_ENC_XOR_KEY KEY, 112, RDK2, %r11d, 6, %r10d, %r9d, 96, %rsp // Round 7 encryption
|
||||
ONE_ENC_XOR_KEY KEY, 128, RDK2, %r11d, 7, %r10d, %r9d, 112, %rsp // Round 8 encryption
|
||||
|
||||
vmovdqu 144(KEY), RDK // Round 9 key Load
|
||||
vmovdqu 160(KEY), RDK2 // Round 10 key Load
|
||||
cmp $12, ROUNDS
|
||||
jb .Lctr_aesenc_8_blks_enc_last
|
||||
|
||||
ONE_ENC RDK, IV0, IV1, IV2, IV3, IV4, IV5, IV6, IV7 // Round 9 encryption
|
||||
vmovdqu 176(KEY), RDK // Round 11 key Load
|
||||
ONE_ENC RDK2, IV0, IV1, IV2, IV3, IV4, IV5, IV6, IV7 // Round 10 encryption
|
||||
vmovdqu 192(KEY), RDK2 // Round 12 key Load
|
||||
|
||||
je .Lctr_aesenc_8_blks_enc_last
|
||||
|
||||
ONE_ENC RDK, IV0, IV1, IV2, IV3, IV4, IV5, IV6, IV7 // Round 11 encryption
|
||||
vmovdqu 208(KEY), RDK // Round 13 key Load
|
||||
ONE_ENC RDK2, IV0, IV1, IV2, IV3, IV4, IV5, IV6, IV7 // Round 12 encryption
|
||||
vmovdqu 224(KEY), RDK2 // Round 14 key Load
|
||||
|
||||
.align 16
|
||||
.Lctr_aesenc_8_blks_enc_last:
|
||||
vpxor (INPUT), RDK2, BLK0 // Last round Key ^ Plaintext.
|
||||
vpxor 16(INPUT), RDK2, BLK1
|
||||
vpxor 32(INPUT), RDK2, BLK2
|
||||
vpxor 48(INPUT), RDK2, BLK3
|
||||
|
||||
ONE_ENC RDK, IV0, IV1, IV2, IV3, IV4, IV5, IV6, IV7
|
||||
|
||||
aesenclast BLK0, IV0 // Last round of encryption.
|
||||
aesenclast BLK1, IV1
|
||||
aesenclast BLK2, IV2
|
||||
aesenclast BLK3, IV3
|
||||
aesenclast RDK2, IV4
|
||||
aesenclast RDK2, IV5
|
||||
aesenclast RDK2, IV6
|
||||
aesenclast RDK2, IV7
|
||||
|
||||
vmovdqu IV0, (OUTPUT) // The first four ciphertexts are stored in out.
|
||||
vmovdqu IV1, 16(OUTPUT)
|
||||
vmovdqu IV2, 32(OUTPUT)
|
||||
vmovdqu IV3, 48(OUTPUT)
|
||||
vpxor 64(INPUT), IV4, BLK0 // Last Round Key ^ Plaintext.
|
||||
vpxor 80(INPUT), IV5, BLK1
|
||||
vpxor 96(INPUT), IV6, BLK2
|
||||
vpxor 112(INPUT), IV7, BLK3
|
||||
|
||||
vmovdqu BLK0, 64(OUTPUT)
|
||||
vmovdqu BLK1, 80(OUTPUT)
|
||||
vmovdqu BLK2, 96(OUTPUT) // The last four ciphertexts are stored in out.
|
||||
vmovdqu BLK3, 112(OUTPUT)
|
||||
vmovdqa (%rsp), IV0 // Reads the next round of ctr from the stack.
|
||||
vmovdqa 16(%rsp), IV1
|
||||
vmovdqa 32(%rsp), IV2
|
||||
vmovdqa 48(%rsp), IV3
|
||||
vmovdqa 64(%rsp), IV4
|
||||
vmovdqa 80(%rsp), IV5
|
||||
vmovdqa 96(%rsp), IV6
|
||||
vmovdqa 112(%rsp), IV7
|
||||
UPDATE_DATA INPUT, OUTPUT, LEN, 128
|
||||
cmpl $0, LEN
|
||||
jbe .Lctr_aesenc_finish
|
||||
jmp .Lctr_aesenc_8_blks_enc_loop
|
||||
|
||||
.Lctr_enc_proc_1_blk:
|
||||
movl 240(KEY), ROUNDS
|
||||
movq KEY, KTMP
|
||||
decl ROUNDS
|
||||
.align 16
|
||||
.Laesenc_loop:
|
||||
leaq 16(KTMP), KTMP
|
||||
vmovdqu (KTMP), RDK
|
||||
aesenc RDK, IV0
|
||||
decl ROUNDS
|
||||
jnz .Laesenc_loop // Loop the loop until the ROUNDS is 0.
|
||||
leaq 16(KTMP), KTMP
|
||||
vmovdqu (KTMP), RDK
|
||||
aesenclast RDK, IV0
|
||||
addl $1, %r11d // Update ctr32.
|
||||
vpxor (INPUT), IV0, BLK0
|
||||
vmovdqu BLK0, (OUTPUT) // Ciphertext stored in out.
|
||||
UPDATE_DATA INPUT, OUTPUT, LEN, 16
|
||||
jmp .Lctr_enc_proc_8_blk
|
||||
.Lctr_enc_proc_2_blk:
|
||||
movl 240(KEY), ROUNDS
|
||||
movq KEY, KTMP
|
||||
decl ROUNDS
|
||||
XOR_KEY %r11d, 1, %r10d, %r9d, 16, %rsp
|
||||
vmovdqa 16(%rsp), IV1
|
||||
.align 16
|
||||
.Laesenc_2_blks_loop:
|
||||
leaq 16(KTMP), KTMP
|
||||
vmovdqu (KTMP), RDK
|
||||
aesenc RDK, IV0
|
||||
aesenc RDK, IV1
|
||||
decl ROUNDS
|
||||
jnz .Laesenc_2_blks_loop
|
||||
leaq 16(KTMP), KTMP
|
||||
vmovdqu (KTMP), RDK
|
||||
aesenclast RDK, IV0
|
||||
aesenclast RDK, IV1
|
||||
|
||||
vpxor (INPUT), IV0, BLK0
|
||||
vpxor 16(INPUT), IV1, BLK1
|
||||
vmovdqu BLK0, (OUTPUT)
|
||||
vmovdqu BLK1, 16(OUTPUT)
|
||||
addl $2, %r11d
|
||||
UPDATE_DATA INPUT, OUTPUT, LEN, 32
|
||||
jmp .Lctr_enc_proc_8_blk
|
||||
.Lctr_enc_proc_3_blk:
|
||||
movl 240(KEY), ROUNDS
|
||||
movq KEY, KTMP
|
||||
decl ROUNDS
|
||||
XOR_KEY %r11d, 1, %r10d, %r9d, 16, %rsp
|
||||
XOR_KEY %r11d, 2, %r10d, %r9d, 32, %rsp
|
||||
vmovdqa 16(%rsp), IV1
|
||||
vmovdqa 32(%rsp), IV2
|
||||
.align 16
|
||||
.Laesenc_3_blks_loop:
|
||||
leaq 16(KTMP), KTMP
|
||||
vmovdqu (KTMP), RDK
|
||||
aesenc RDK, IV0
|
||||
aesenc RDK, IV1
|
||||
aesenc RDK, IV2
|
||||
decl ROUNDS
|
||||
jnz .Laesenc_3_blks_loop
|
||||
leaq 16(KTMP), KTMP
|
||||
vmovdqu (KTMP), RDK
|
||||
aesenclast RDK, IV0
|
||||
aesenclast RDK, IV1
|
||||
aesenclast RDK, IV2
|
||||
|
||||
vpxor (INPUT), IV0, BLK0
|
||||
vpxor 16(INPUT), IV1, BLK1
|
||||
vpxor 32(INPUT), IV2, BLK2
|
||||
|
||||
vmovdqu BLK0, (OUTPUT)
|
||||
vmovdqu BLK1, 16(OUTPUT)
|
||||
vmovdqu BLK2, 32(OUTPUT)
|
||||
addl $3, %r11d
|
||||
UPDATE_DATA INPUT, OUTPUT, LEN, 48
|
||||
jmp .Lctr_enc_proc_8_blk
|
||||
.Lctr_enc_proc_4_blk:
|
||||
movl 240(KEY), ROUNDS
|
||||
movq KEY, KTMP
|
||||
decl ROUNDS
|
||||
XOR_KEY %r11d, 1, %r10d, %r9d, 16, %rsp
|
||||
XOR_KEY %r11d, 2, %r10d, %r9d, 32, %rsp
|
||||
XOR_KEY %r11d, 3, %r10d, %r9d, 48, %rsp
|
||||
vmovdqa 16(%rsp), IV1
|
||||
vmovdqa 32(%rsp), IV2
|
||||
vmovdqa 48(%rsp), IV3
|
||||
.align 16
|
||||
.Laesenc_4_blks_loop:
|
||||
leaq 16(KTMP), KTMP
|
||||
vmovdqu (KTMP), RDK
|
||||
aesenc RDK, IV0
|
||||
aesenc RDK, IV1
|
||||
aesenc RDK, IV2
|
||||
aesenc RDK, IV3
|
||||
decl ROUNDS
|
||||
jnz .Laesenc_4_blks_loop
|
||||
leaq 16(KTMP), KTMP
|
||||
vmovdqu (KTMP), RDK
|
||||
aesenclast RDK, IV0
|
||||
aesenclast RDK, IV1
|
||||
aesenclast RDK, IV2
|
||||
aesenclast RDK, IV3
|
||||
|
||||
vpxor (INPUT), IV0, BLK0
|
||||
vpxor 16(INPUT), IV1, BLK1
|
||||
vpxor 32(INPUT), IV2, BLK2
|
||||
vpxor 48(INPUT), IV3, BLK3
|
||||
|
||||
vmovdqu BLK0, (OUTPUT)
|
||||
vmovdqu BLK1, 16(OUTPUT)
|
||||
vmovdqu BLK2, 32(OUTPUT)
|
||||
vmovdqu BLK3, 48(OUTPUT)
|
||||
addl $4, %r11d
|
||||
UPDATE_DATA INPUT, OUTPUT, LEN, 64
|
||||
jmp .Lctr_enc_proc_8_blk
|
||||
|
||||
.Lctr_enc_proc_5_blk:
|
||||
movl 240(KEY), ROUNDS
|
||||
movq KEY, KTMP
|
||||
decl ROUNDS
|
||||
XOR_KEY %r11d, 1, %r10d, %r9d, 16, %rsp
|
||||
XOR_KEY %r11d, 2, %r10d, %r9d, 32, %rsp
|
||||
XOR_KEY %r11d, 3, %r10d, %r9d, 48, %rsp
|
||||
XOR_KEY %r11d, 4, %r10d, %r9d, 64, %rsp
|
||||
vmovdqa 16(%rsp), IV1
|
||||
vmovdqa 32(%rsp), IV2
|
||||
vmovdqa 48(%rsp), IV3
|
||||
vmovdqa 64(%rsp), IV4
|
||||
.align 16
|
||||
.Laesenc_5_blks_loop:
|
||||
leaq 16(KTMP), KTMP
|
||||
vmovdqu (KTMP), RDK
|
||||
aesenc RDK, IV0
|
||||
aesenc RDK, IV1
|
||||
aesenc RDK, IV2
|
||||
aesenc RDK, IV3
|
||||
aesenc RDK, IV4
|
||||
decl ROUNDS
|
||||
jnz .Laesenc_5_blks_loop
|
||||
leaq 16(KTMP), KTMP
|
||||
vmovdqu (KTMP), RDK
|
||||
aesenclast RDK, IV0
|
||||
aesenclast RDK, IV1
|
||||
aesenclast RDK, IV2
|
||||
aesenclast RDK, IV3
|
||||
aesenclast RDK, IV4
|
||||
|
||||
vpxor (INPUT), IV0, BLK0
|
||||
vpxor 16(INPUT), IV1, BLK1
|
||||
vpxor 32(INPUT), IV2, BLK2
|
||||
vpxor 48(INPUT), IV3, BLK3
|
||||
vpxor 64(INPUT), IV4, BLK4
|
||||
vmovdqu BLK0, (OUTPUT)
|
||||
vmovdqu BLK1, 16(OUTPUT)
|
||||
vmovdqu BLK2, 32(OUTPUT)
|
||||
vmovdqu BLK3, 48(OUTPUT)
|
||||
vmovdqu BLK4, 64(OUTPUT)
|
||||
addl $5, %r11d
|
||||
UPDATE_DATA INPUT, OUTPUT, LEN, 80
|
||||
jmp .Lctr_enc_proc_8_blk
|
||||
.Lctr_enc_proc_6_blk:
|
||||
movl 240(KEY), ROUNDS
|
||||
movq KEY, KTMP
|
||||
decl ROUNDS
|
||||
XOR_KEY %r11d, 1, %r10d, %r9d, 16, %rsp
|
||||
XOR_KEY %r11d, 2, %r10d, %r9d, 32, %rsp
|
||||
XOR_KEY %r11d, 3, %r10d, %r9d, 48, %rsp
|
||||
XOR_KEY %r11d, 4, %r10d, %r9d, 64, %rsp
|
||||
XOR_KEY %r11d, 5, %r10d, %r9d, 80, %rsp
|
||||
vmovdqa 16(%rsp), IV1
|
||||
vmovdqa 32(%rsp), IV2
|
||||
vmovdqa 48(%rsp), IV3
|
||||
vmovdqa 64(%rsp), IV4
|
||||
vmovdqa 80(%rsp), IV5
|
||||
.align 16
|
||||
.Laesenc_6_blks_loop:
|
||||
leaq 16(KTMP), KTMP
|
||||
vmovdqu (KTMP), RDK
|
||||
aesenc RDK, IV0
|
||||
aesenc RDK, IV1
|
||||
aesenc RDK, IV2
|
||||
aesenc RDK, IV3
|
||||
aesenc RDK, IV4
|
||||
aesenc RDK, IV5
|
||||
decl ROUNDS
|
||||
jnz .Laesenc_6_blks_loop
|
||||
leaq 16(KTMP), KTMP
|
||||
vmovdqu (KTMP), RDK
|
||||
aesenclast RDK, IV0
|
||||
aesenclast RDK, IV1
|
||||
aesenclast RDK, IV2
|
||||
aesenclast RDK, IV3
|
||||
aesenclast RDK, IV4
|
||||
aesenclast RDK, IV5
|
||||
|
||||
vpxor (INPUT), IV0, BLK0
|
||||
vpxor 16(INPUT), IV1, BLK1
|
||||
vpxor 32(INPUT), IV2, BLK2
|
||||
vpxor 48(INPUT), IV3, BLK3
|
||||
vpxor 64(INPUT), IV4, BLK4
|
||||
vpxor 80(INPUT), IV5, BLK5
|
||||
vmovdqu BLK0, (OUTPUT)
|
||||
vmovdqu BLK1, 16(OUTPUT)
|
||||
vmovdqu BLK2, 32(OUTPUT)
|
||||
vmovdqu BLK3, 48(OUTPUT)
|
||||
vmovdqu BLK4, 64(OUTPUT)
|
||||
vmovdqu BLK5, 80(OUTPUT)
|
||||
addl $6, %r11d
|
||||
UPDATE_DATA INPUT, OUTPUT, LEN, 96
|
||||
|
||||
jmp .Lctr_enc_proc_8_blk
|
||||
.Lctr_enc_proc_7_blk:
|
||||
movl 240(KEY), ROUNDS
|
||||
movq KEY, KTMP
|
||||
decl ROUNDS
|
||||
XOR_KEY %r11d, 1, %r10d, %r9d, 16, %rsp
|
||||
XOR_KEY %r11d, 2, %r10d, %r9d, 32, %rsp
|
||||
XOR_KEY %r11d, 3, %r10d, %r9d, 48, %rsp
|
||||
XOR_KEY %r11d, 4, %r10d, %r9d, 64, %rsp
|
||||
XOR_KEY %r11d, 5, %r10d, %r9d, 80, %rsp
|
||||
XOR_KEY %r11d, 6, %r10d, %r9d, 96, %rsp
|
||||
vmovdqa 16(%rsp), IV1
|
||||
vmovdqa 32(%rsp), IV2
|
||||
vmovdqa 48(%rsp), IV3
|
||||
vmovdqa 64(%rsp), IV4
|
||||
vmovdqa 80(%rsp), IV5
|
||||
vmovdqa 96(%rsp), IV6
|
||||
|
||||
.align 16
|
||||
.Laesenc_7_blks_loop:
|
||||
leaq 16(KTMP), KTMP
|
||||
vmovdqu (KTMP), RDK
|
||||
aesenc RDK, IV0
|
||||
aesenc RDK, IV1
|
||||
aesenc RDK, IV2
|
||||
aesenc RDK, IV3
|
||||
aesenc RDK, IV4
|
||||
aesenc RDK, IV5
|
||||
aesenc RDK, IV6
|
||||
decl ROUNDS
|
||||
jnz .Laesenc_7_blks_loop
|
||||
leaq 16(KTMP), KTMP
|
||||
vmovdqu (KTMP), RDK
|
||||
aesenclast RDK, IV0
|
||||
aesenclast RDK, IV1
|
||||
aesenclast RDK, IV2
|
||||
aesenclast RDK, IV3
|
||||
aesenclast RDK, IV4
|
||||
aesenclast RDK, IV5
|
||||
aesenclast RDK, IV6
|
||||
vpxor (INPUT), IV0, BLK0
|
||||
vpxor 16(INPUT), IV1, BLK1
|
||||
vpxor 32(INPUT), IV2, BLK2
|
||||
vpxor 48(INPUT), IV3, BLK3
|
||||
vmovdqu BLK0, (OUTPUT)
|
||||
vmovdqu BLK1, 16(OUTPUT)
|
||||
vmovdqu BLK2, 32(OUTPUT)
|
||||
vmovdqu BLK3, 48(OUTPUT)
|
||||
vpxor 64(INPUT), IV4, BLK0
|
||||
vpxor 80(INPUT), IV5, BLK1
|
||||
vpxor 96(INPUT), IV6, BLK2
|
||||
vmovdqu BLK0, 64(OUTPUT)
|
||||
vmovdqu BLK1, 80(OUTPUT)
|
||||
vmovdqu BLK2, 96(OUTPUT)
|
||||
addl $7, %r11d
|
||||
UPDATE_DATA INPUT, OUTPUT, LEN, 112
|
||||
jmp .Lctr_enc_proc_8_blk
|
||||
|
||||
.Lctr_aesenc_finish:
|
||||
bswap %r11d
|
||||
movl %r11d, 12(CTR_IV)
|
||||
vpxor IV0, IV0, IV0
|
||||
vpxor IV1, IV1, IV1
|
||||
vpxor IV2, IV2, IV2
|
||||
vpxor IV3, IV3, IV3
|
||||
vpxor IV4, IV4, IV4
|
||||
vpxor IV5, IV5, IV5
|
||||
vpxor IV6, IV6, IV6
|
||||
vpxor IV7, IV7, IV7
|
||||
vpxor RDK, RDK, RDK
|
||||
vmovdqa IV0, 0(%rsp)
|
||||
vmovdqa IV0, 16(%rsp)
|
||||
vmovdqa IV0, 32(%rsp)
|
||||
vmovdqa IV0, 48(%rsp)
|
||||
vmovdqa IV0, 64(%rsp)
|
||||
vmovdqa IV0, 80(%rsp)
|
||||
vmovdqa IV0, 96(%rsp)
|
||||
vmovdqa IV0, 112(%rsp)
|
||||
|
||||
movq %r12, %rsp
|
||||
popq %r14
|
||||
popq %r13
|
||||
popq %r12
|
||||
|
||||
movl $0, RET
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size CRYPT_AES_CTR_Encrypt, .-CRYPT_AES_CTR_Encrypt
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_ECB)
|
||||
|
||||
#include "crypt_aes_macro_armv8.s"
|
||||
#include "crypt_arm.h"
|
||||
|
||||
.file "crypt_aes_ecb_armv8.S"
|
||||
.text
|
||||
.arch armv8-a+crypto
|
||||
|
||||
KEY .req x0
|
||||
IN .req x1
|
||||
OUT .req x2
|
||||
LEN .req x3
|
||||
|
||||
KTMP .req x4
|
||||
LTMP .req x9
|
||||
|
||||
ROUNDS .req w6
|
||||
|
||||
BLK0 .req v0
|
||||
BLK1 .req v1
|
||||
BLK2 .req v2
|
||||
BLK3 .req v3
|
||||
BLK4 .req v4
|
||||
BLK5 .req v5
|
||||
BLK6 .req v6
|
||||
BLK7 .req v7
|
||||
|
||||
RDK0 .req v17
|
||||
RDK1 .req v18
|
||||
|
||||
/*
|
||||
* Vn - V0 ~ V31
|
||||
* 8bytes - Vn.8B Vn.4H Vn.2S Vn.1D
|
||||
* 16bytes - Vn.16B Vn.8H Vn.4S Vn.2D
|
||||
*
|
||||
* In Return-oriented programming (ROP) and Jump-oriented programming (JOP), we explored features
|
||||
* that Arm introduced to the Arm architecture to mitigate against JOP-style and ROP-style attacks.
|
||||
* ...
|
||||
* Whether the combined or NOP-compatible instructions are generated depends on the architecture
|
||||
* version that the code is built for. When building for Armv8.3-A, or later, the compiler will use
|
||||
* the combined operations. When building for Armv8.2-A, or earlier, it will use the NOP compatible
|
||||
* instructions.
|
||||
* (https://developer.arm.com/documentation/102433/0100/Applying-these-techniques-to-real-code?lang=en)
|
||||
*
|
||||
* The paciasp and autiasp instructions are used for function pointer authentication. The pointer
|
||||
* authentication feature is added in armv8.3 and is supported only by AArch64.
|
||||
* The addition of pointer authentication features is described in Section A2.6.1 of
|
||||
* DDI0487H_a_a-profile_architecture_reference_manual.pdf.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function description: Sets the AES encryption assembly acceleration interface in ECB mode.
|
||||
* int32_t CRYPT_AES_ECB_Encrypt(const CRYPT_AES_Key *ctx,
|
||||
* const uint8_t *in,
|
||||
* uint8_t *out,
|
||||
* uint32_t len);
|
||||
* Input register:
|
||||
* x0: Pointer to the input key structure.
|
||||
* x1: Points to the 128-bit input data.
|
||||
* x2: Points to the 128-bit output data.
|
||||
* x3: Indicates the length of a data block, that is, 16 bytes.
|
||||
* Change register: x4, x6, x9, v0-v7, v17, v18.
|
||||
* Output register: x0.
|
||||
* Function/Macro Call: AES_ENC_8_BLKS, AES_ENC_1_BLK, AES_ENC_2_BLKS, AES_ENC_4_BLKS,
|
||||
* AES_ENC_5_BLKS, AES_ENC_6_BLKS, AES_ENC_7_BLKS.
|
||||
*/
|
||||
.globl CRYPT_AES_ECB_Encrypt
|
||||
.type CRYPT_AES_ECB_Encrypt, %function
|
||||
CRYPT_AES_ECB_Encrypt:
|
||||
.inst 0xd503233f // paciasp
|
||||
mov LTMP, LEN
|
||||
.Lecb_aesenc_start:
|
||||
cmp LTMP, #64
|
||||
b.ge .Lecb_enc_above_equal_4_blks
|
||||
cmp LTMP, #32
|
||||
b.ge .Lecb_enc_above_equal_2_blks
|
||||
cmp LTMP, #0
|
||||
b.eq .Lecb_aesenc_finish
|
||||
b .Lecb_enc_proc_1_blk
|
||||
|
||||
.Lecb_enc_above_equal_2_blks:
|
||||
cmp LTMP, #48
|
||||
b.lt .Lecb_enc_proc_2_blks
|
||||
b .Lecb_enc_proc_3_blks
|
||||
|
||||
.Lecb_enc_above_equal_4_blks:
|
||||
cmp LTMP, #96
|
||||
b.ge .Lecb_enc_above_equal_6_blks
|
||||
cmp LTMP, #80
|
||||
b.lt .Lecb_enc_proc_4_blks
|
||||
b .Lecb_enc_proc_5_blks
|
||||
|
||||
.Lecb_enc_above_equal_6_blks:
|
||||
cmp LTMP, #112
|
||||
b.lt .Lecb_enc_proc_6_blks
|
||||
cmp LTMP, #128
|
||||
b.lt .Lecb_enc_proc_7_blks
|
||||
|
||||
.Lecb_enc_proc_8_blks:
|
||||
.Lecb_aesenc_8_blks_loop:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b}, [IN], #64
|
||||
mov KTMP, KEY
|
||||
AES_ENC_8_BLKS KTMP BLK0.16b BLK1.16b BLK2.16b BLK3.16b BLK4.16b \
|
||||
BLK5.16b BLK6.16b BLK7.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b}, [OUT], #64
|
||||
sub LTMP, LTMP, #128
|
||||
cmp LTMP, #128
|
||||
b.lt .Lecb_aesenc_start
|
||||
b .Lecb_aesenc_8_blks_loop
|
||||
|
||||
.Lecb_enc_proc_1_blk:
|
||||
ld1 {BLK0.16b}, [IN]
|
||||
AES_ENC_1_BLK KEY BLK0.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b}, [OUT]
|
||||
b .Lecb_aesenc_finish
|
||||
|
||||
.Lecb_enc_proc_2_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b}, [IN]
|
||||
AES_ENC_2_BLKS KEY BLK0.16b BLK1.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b, BLK1.16b}, [OUT]
|
||||
b .Lecb_aesenc_finish
|
||||
|
||||
.Lecb_enc_proc_3_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b}, [IN]
|
||||
AES_ENC_3_BLKS KEY BLK0.16b BLK1.16b BLK2.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b}, [OUT]
|
||||
b .Lecb_aesenc_finish
|
||||
|
||||
.Lecb_enc_proc_4_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN]
|
||||
AES_ENC_4_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT]
|
||||
b .Lecb_aesenc_finish
|
||||
|
||||
.Lecb_enc_proc_5_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b}, [IN]
|
||||
AES_ENC_5_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b BLK4.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b}, [OUT]
|
||||
b .Lecb_aesenc_finish
|
||||
|
||||
.Lecb_enc_proc_6_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b, BLK5.16b}, [IN]
|
||||
AES_ENC_6_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b BLK4.16b BLK5.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b, BLK5.16b}, [OUT]
|
||||
b .Lecb_aesenc_finish
|
||||
|
||||
.Lecb_enc_proc_7_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b, BLK5.16b, BLK6.16b}, [IN]
|
||||
AES_ENC_7_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b BLK4.16b BLK5.16b BLK6.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b, BLK5.16b, BLK6.16b}, [OUT]
|
||||
|
||||
.Lecb_aesenc_finish:
|
||||
mov x0, #0
|
||||
eor RDK0.16b, RDK0.16b, RDK0.16b
|
||||
eor RDK1.16b, RDK1.16b, RDK1.16b
|
||||
.inst 0xd50323bf // Autiasp
|
||||
ret
|
||||
.size CRYPT_AES_ECB_Encrypt, .-CRYPT_AES_ECB_Encrypt
|
||||
|
||||
|
||||
/**
|
||||
* Function description: Sets the AES decryption and assembly acceleration API in ECB mode.
|
||||
* int32_t CRYPT_AES_ECB_Decrypt(const CRYPT_AES_Key *ctx,
|
||||
* const uint8_t *in,
|
||||
* uint8_t *out,
|
||||
* uint32_t len);
|
||||
* Input register:
|
||||
* x0: Pointer to the input key structure.
|
||||
* x1: Points to the 128-bit input data.
|
||||
* x2: Points to the 128-bit output data.
|
||||
* x3: Indicates the length of a data block, that is, 16 bytes.
|
||||
* Change register: x4, x6, x9, v0-v7, v17, v18
|
||||
* Output register: x0
|
||||
* Function/Macro Call: AES_DEC_8_BLKS, AES_DEC_1_BLK, AES_DEC_2_BLKS, AES_DEC_4_BLKS,
|
||||
* AES_DEC_5_BLKS, AES_DEC_6_BLKS, AES_DEC_7_BLKS.
|
||||
*/
|
||||
.globl CRYPT_AES_ECB_Decrypt
|
||||
.type CRYPT_AES_ECB_Decrypt, %function
|
||||
CRYPT_AES_ECB_Decrypt:
|
||||
.inst 0xd503233f // paciasp
|
||||
mov LTMP, LEN
|
||||
.Lecb_aesdec_start:
|
||||
cmp LTMP, #64
|
||||
b.ge .Lecb_dec_above_equal_4_blks
|
||||
cmp LTMP, #32
|
||||
b.ge .Lecb_dec_above_equal_2_blks
|
||||
cmp LTMP, #0
|
||||
b.eq .Lecb_aesdec_finish
|
||||
b .Lecb_dec_proc_1_blk
|
||||
|
||||
.Lecb_dec_above_equal_2_blks:
|
||||
cmp LTMP, #48
|
||||
b.lt .Lecb_dec_proc_2_blks
|
||||
b .Lecb_dec_proc_3_blks
|
||||
|
||||
.Lecb_dec_above_equal_4_blks:
|
||||
cmp LTMP, #96
|
||||
b.ge .Lecb_dec_above_equal_6_blks
|
||||
cmp LTMP, #80
|
||||
b.lt .Lecb_dec_proc_4_blks
|
||||
b .Lecb_dec_proc_5_blks
|
||||
|
||||
|
||||
.Lecb_dec_above_equal_6_blks:
|
||||
cmp LTMP, #112
|
||||
b.lt .Lecb_dec_proc_6_blks
|
||||
cmp LTMP, #128
|
||||
b.lt .Lecb_dec_proc_7_blks
|
||||
|
||||
.Lecb_dec_proc_8_blks:
|
||||
.Lecb_aesdec_8_blks_loop:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b}, [IN], #64
|
||||
mov KTMP, KEY
|
||||
AES_DEC_8_BLKS KTMP BLK0.16b BLK1.16b BLK2.16b BLK3.16b BLK4.16b \
|
||||
BLK5.16b BLK6.16b BLK7.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b, BLK5.16b, BLK6.16b, BLK7.16b}, [OUT], #64
|
||||
sub LTMP, LTMP, #128
|
||||
cmp LTMP, #128
|
||||
b.lt .Lecb_aesdec_start
|
||||
b .Lecb_aesdec_8_blks_loop
|
||||
|
||||
.Lecb_dec_proc_1_blk:
|
||||
ld1 {BLK0.16b}, [IN]
|
||||
AES_DEC_1_BLK KEY BLK0.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b}, [OUT]
|
||||
b .Lecb_aesdec_finish
|
||||
|
||||
.Lecb_dec_proc_2_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b}, [IN]
|
||||
AES_DEC_2_BLKS KEY BLK0.16b BLK1.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b, BLK1.16b}, [OUT]
|
||||
b .Lecb_aesdec_finish
|
||||
|
||||
.Lecb_dec_proc_3_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b}, [IN]
|
||||
AES_DEC_3_BLKS KEY BLK0.16b BLK1.16b BLK2.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b}, [OUT]
|
||||
b .Lecb_aesdec_finish
|
||||
|
||||
.Lecb_dec_proc_4_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN]
|
||||
AES_DEC_4_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT]
|
||||
b .Lecb_aesdec_finish
|
||||
|
||||
.Lecb_dec_proc_5_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b}, [IN]
|
||||
AES_DEC_5_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b BLK4.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b}, [OUT]
|
||||
b .Lecb_aesdec_finish
|
||||
|
||||
.Lecb_dec_proc_6_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b, BLK5.16b}, [IN]
|
||||
AES_DEC_6_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b BLK4.16b BLK5.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b, BLK5.16b}, [OUT]
|
||||
b .Lecb_aesdec_finish
|
||||
|
||||
.Lecb_dec_proc_7_blks:
|
||||
ld1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [IN], #64
|
||||
ld1 {BLK4.16b, BLK5.16b, BLK6.16b}, [IN]
|
||||
AES_DEC_7_BLKS KEY BLK0.16b BLK1.16b BLK2.16b BLK3.16b BLK4.16b BLK5.16b BLK6.16b RDK0.4s RDK1.4s RDK0.16b RDK1.16b ROUNDS
|
||||
st1 {BLK0.16b, BLK1.16b, BLK2.16b, BLK3.16b}, [OUT], #64
|
||||
st1 {BLK4.16b, BLK5.16b, BLK6.16b}, [OUT]
|
||||
|
||||
.Lecb_aesdec_finish:
|
||||
mov x0, #0
|
||||
eor RDK0.16b, RDK0.16b, RDK0.16b
|
||||
eor RDK1.16b, RDK1.16b, RDK1.16b
|
||||
.inst 0xd50323bf // Autiasp
|
||||
ret
|
||||
.size CRYPT_AES_ECB_Decrypt, .-CRYPT_AES_ECB_Decrypt
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,548 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_ECB)
|
||||
|
||||
#include "crypt_aes_macro_x86_64.s"
|
||||
|
||||
.file "crypt_aes_ecb_x86_64.S"
|
||||
.text
|
||||
|
||||
.set ARG1, %rdi
|
||||
.set ARG2, %rsi
|
||||
.set ARG3, %rdx
|
||||
.set ARG4, %ecx
|
||||
.set ARG5, %r8
|
||||
.set ARG6, %r9
|
||||
|
||||
.set RDK, %xmm3
|
||||
.set KEY, %rdi
|
||||
.set KTMP, %r9
|
||||
.set ROUNDS, %eax
|
||||
.set RET, %eax
|
||||
|
||||
.set BLK0, %xmm1
|
||||
.set BLK1, %xmm4
|
||||
.set BLK2, %xmm5
|
||||
.set BLK3, %xmm6
|
||||
.set BLK4, %xmm10
|
||||
.set BLK5, %xmm11
|
||||
.set BLK6, %xmm12
|
||||
.set BLK7, %xmm13
|
||||
.set BLK8, %xmm0
|
||||
.set BLK9, %xmm2
|
||||
.set BLK10, %xmm7
|
||||
.set BLK11, %xmm8
|
||||
.set BLK12, %xmm9
|
||||
.set BLK13, %xmm14
|
||||
|
||||
|
||||
/**
|
||||
* Function description: Sets the AES encryption assembly acceleration API in ECB mode.
|
||||
* Function prototype: int32_t CRYPT_AES_ECB_Encrypt(const CRYPT_AES_Key *ctx,
|
||||
* const uint8_t *in, uint8_t *out, uint32_t len);
|
||||
* Input register:
|
||||
* x0: Pointer to the input key structure.
|
||||
* x1: Points to the 128-bit input data.
|
||||
* x2: Points to the 128-bit output data.
|
||||
* x3: Indicates the length of a data block, that is, 16 bytes.
|
||||
* Change register: xmm1,xmm3,xmm4,xmm5,xmm6,xmm10,xmm11,xmm12,xmm13.
|
||||
* Output register: eax.
|
||||
* Function/Macro Call: None.
|
||||
*/
|
||||
|
||||
.globl CRYPT_AES_ECB_Encrypt
|
||||
.type CRYPT_AES_ECB_Encrypt, @function
|
||||
CRYPT_AES_ECB_Encrypt:
|
||||
.cfi_startproc
|
||||
.align 16
|
||||
.Lecb_aesenc_start:
|
||||
cmpl $64, ARG4
|
||||
jae .Lecb_enc_above_equal_4_blks
|
||||
cmpl $32, ARG4
|
||||
jae .Lecb_enc_above_equal_2_blks
|
||||
cmpl $0, ARG4
|
||||
je .Lecb_aesdec_finish
|
||||
jmp .Lecb_enc_proc_1_blk
|
||||
|
||||
.Lecb_enc_above_equal_2_blks:
|
||||
cmpl $48, ARG4
|
||||
jb .Lecb_enc_proc_2_blks
|
||||
jmp .Lecb_enc_proc_3_blks
|
||||
|
||||
.Lecb_enc_above_equal_4_blks:
|
||||
cmpl $96, ARG4
|
||||
jae .Lecb_enc_above_equal_6_blks
|
||||
cmpl $80, ARG4
|
||||
jb .Lecb_enc_proc_4_blks
|
||||
jmp .Lecb_enc_proc_5_blks
|
||||
|
||||
.Lecb_enc_above_equal_6_blks:
|
||||
cmpl $112, ARG4
|
||||
jb .Lecb_enc_proc_6_blks
|
||||
cmpl $128, ARG4
|
||||
jb .Lecb_enc_proc_7_blks
|
||||
cmpl $256, ARG4
|
||||
jbe .Lecb_enc_proc_8_blks
|
||||
|
||||
.align 16
|
||||
.ecb_enc_proc_14_blks:
|
||||
.Lecb_aesenc_14_blks_loop:
|
||||
movq KEY, KTMP
|
||||
vmovdqu (KEY), RDK
|
||||
movl 240(KEY), ROUNDS
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
vpxor 64(ARG2), RDK, BLK4
|
||||
vpxor 80(ARG2), RDK, BLK5
|
||||
vpxor 96(ARG2), RDK, BLK6
|
||||
vpxor 112(ARG2), RDK, BLK7
|
||||
vpxor 128(ARG2), RDK, BLK8
|
||||
vpxor 144(ARG2), RDK, BLK9
|
||||
vpxor 160(ARG2), RDK, BLK10
|
||||
vpxor 176(ARG2), RDK, BLK11
|
||||
vpxor 192(ARG2), RDK, BLK12
|
||||
vpxor 208(ARG2), RDK, BLK13
|
||||
decl ROUNDS
|
||||
AES_ENC_14_BLKS ARG2 KTMP ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 BLK5 BLK6 BLK7 BLK8 BLK9 BLK10 BLK11 BLK12 BLK13
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
vmovdqu BLK4, 64(ARG3)
|
||||
vmovdqu BLK5, 80(ARG3)
|
||||
vmovdqu BLK6, 96(ARG3)
|
||||
vmovdqu BLK7, 112(ARG3)
|
||||
vmovdqu BLK8, 128(ARG3)
|
||||
vmovdqu BLK9, 144(ARG3)
|
||||
vmovdqu BLK10, 160(ARG3)
|
||||
vmovdqu BLK11, 176(ARG3)
|
||||
vmovdqu BLK12, 192(ARG3)
|
||||
vmovdqu BLK13, 208(ARG3)
|
||||
leaq 224(ARG2), ARG2
|
||||
leaq 224(ARG3), ARG3
|
||||
subl $224, ARG4
|
||||
cmpl $224, ARG4
|
||||
jb .Lecb_aesenc_start
|
||||
jmp .Lecb_aesenc_14_blks_loop
|
||||
|
||||
.align 16
|
||||
.Lecb_enc_proc_8_blks:
|
||||
.Lecb_aesenc_8_blks_loop:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
movq KEY, KTMP
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
vpxor 64(ARG2), RDK, BLK4
|
||||
vpxor 80(ARG2), RDK, BLK5
|
||||
vpxor 96(ARG2), RDK, BLK6
|
||||
vpxor 112(ARG2), RDK, BLK7
|
||||
decl ROUNDS
|
||||
AES_ENC_8_BLKS KTMP ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 BLK5 BLK6 BLK7
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
vmovdqu BLK4, 64(ARG3)
|
||||
vmovdqu BLK5, 80(ARG3)
|
||||
vmovdqu BLK6, 96(ARG3)
|
||||
vmovdqu BLK7, 112(ARG3)
|
||||
leaq 128(ARG2), ARG2
|
||||
leaq 128(ARG3), ARG3
|
||||
subl $128, ARG4
|
||||
cmpl $128, ARG4
|
||||
jb .Lecb_aesenc_start
|
||||
jmp .Lecb_aesenc_8_blks_loop
|
||||
|
||||
.align 16
|
||||
.Lecb_enc_proc_1_blk:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
decl ROUNDS
|
||||
AES_ENC_1_BLK KEY ROUNDS RDK BLK0
|
||||
vmovdqu BLK0, (ARG3)
|
||||
jmp .Lecb_aesenc_finish
|
||||
|
||||
.align 16
|
||||
.Lecb_enc_proc_2_blks:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
decl ROUNDS
|
||||
AES_ENC_2_BLKS KEY ROUNDS RDK BLK0 BLK1
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
jmp .Lecb_aesenc_finish
|
||||
|
||||
.align 16
|
||||
.Lecb_enc_proc_3_blks:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
decl ROUNDS
|
||||
AES_ENC_3_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
jmp .Lecb_aesenc_finish
|
||||
|
||||
.align 16
|
||||
.Lecb_enc_proc_4_blks:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
decl ROUNDS
|
||||
AES_ENC_4_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
jmp .Lecb_aesenc_finish
|
||||
|
||||
.align 16
|
||||
.Lecb_enc_proc_5_blks:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
vpxor 64(ARG2), RDK, BLK4
|
||||
decl ROUNDS
|
||||
AES_ENC_5_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
vmovdqu BLK4, 64(ARG3)
|
||||
jmp .Lecb_aesenc_finish
|
||||
|
||||
.align 16
|
||||
.Lecb_enc_proc_6_blks:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
vpxor 64(ARG2), RDK, BLK4
|
||||
vpxor 80(ARG2), RDK, BLK5
|
||||
decl ROUNDS
|
||||
AES_ENC_6_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 BLK5
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
vmovdqu BLK4, 64(ARG3)
|
||||
vmovdqu BLK5, 80(ARG3)
|
||||
jmp .Lecb_aesenc_finish
|
||||
|
||||
.align 16
|
||||
.Lecb_enc_proc_7_blks:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
vpxor 64(ARG2), RDK, BLK4
|
||||
vpxor 80(ARG2), RDK, BLK5
|
||||
vpxor 96(ARG2), RDK, BLK6
|
||||
decl ROUNDS
|
||||
AES_ENC_7_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 BLK5 BLK6
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
vmovdqu BLK4, 64(ARG3)
|
||||
vmovdqu BLK5, 80(ARG3)
|
||||
vmovdqu BLK6, 96(ARG3)
|
||||
|
||||
.align 16
|
||||
.Lecb_aesenc_finish:
|
||||
vpxor RDK, RDK, RDK
|
||||
movl $0, RET
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size CRYPT_AES_ECB_Encrypt, .-CRYPT_AES_ECB_Encrypt
|
||||
|
||||
|
||||
/**
|
||||
* Function description: Sets the AES decryption and assembly acceleration API in ECB mode.
|
||||
* Function prototype: int32_t CRYPT_AES_ECB_Decrypt(const CRYPT_AES_Key *ctx,
|
||||
* const uint8_t *in, uint8_t *out, uint32_t len);
|
||||
* Input register:
|
||||
* x0: Pointer to the input key structure.
|
||||
* x1: Points to the 128-bit input data.
|
||||
* x2: Indicates the 128-bit output data.
|
||||
* x3: Indicates the length of a data block, that is, 16 bytes.
|
||||
* Change register: xmm1,xmm3,xmm4,xmm5,xmm6,xmm10,xmm11,xmm12,xmm13.
|
||||
* Output register: eax.
|
||||
* Function/Macro Call: None.
|
||||
*/
|
||||
.globl CRYPT_AES_ECB_Decrypt
|
||||
.type CRYPT_AES_ECB_Decrypt, @function
|
||||
CRYPT_AES_ECB_Decrypt:
|
||||
.cfi_startproc
|
||||
.align 16
|
||||
.ecb_aesdec_start:
|
||||
cmpl $64, ARG4
|
||||
jae .ecb_dec_above_equal_4_blks
|
||||
cmpl $32, ARG4
|
||||
jae .ecb_dec_above_equal_2_blks
|
||||
cmpl $0, ARG4
|
||||
je .Lecb_aesdec_finish
|
||||
jmp .ecb_dec_proc_1_blk
|
||||
.ecb_dec_above_equal_2_blks:
|
||||
cmpl $48, ARG4
|
||||
jb .ecb_dec_proc_2_blks
|
||||
jmp .ecb_dec_proc_3_blks
|
||||
|
||||
.ecb_dec_above_equal_4_blks:
|
||||
cmpl $96, ARG4
|
||||
jae .ecb_dec_above_equal_6_blks
|
||||
cmpl $80, ARG4
|
||||
jb .ecb_dec_proc_4_blks
|
||||
jmp .ecb_dec_proc_5_blks
|
||||
|
||||
.ecb_dec_above_equal_6_blks:
|
||||
cmpl $112, ARG4
|
||||
jb .ecb_dec_proc_6_blks
|
||||
cmpl $128, ARG4
|
||||
jb .ecb_dec_proc_7_blks
|
||||
cmpl $256, ARG4
|
||||
jbe .ecb_dec_proc_8_blks
|
||||
|
||||
.align 16
|
||||
.ecb_dec_proc_14_blks:
|
||||
.ecb_aesdec_14_blks_loop:
|
||||
movq KEY, KTMP
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
vpxor 64(ARG2), RDK, BLK4
|
||||
vpxor 80(ARG2), RDK, BLK5
|
||||
vpxor 96(ARG2), RDK, BLK6
|
||||
vpxor 112(ARG2), RDK, BLK7
|
||||
vpxor 128(ARG2), RDK, BLK8
|
||||
vpxor 144(ARG2), RDK, BLK9
|
||||
vpxor 160(ARG2), RDK, BLK10
|
||||
vpxor 176(ARG2), RDK, BLK11
|
||||
vpxor 192(ARG2), RDK, BLK12
|
||||
vpxor 208(ARG2), RDK, BLK13
|
||||
decl ROUNDS
|
||||
AES_DEC_14_BLKS KTMP ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 BLK5 BLK6 BLK7 BLK8 BLK9 BLK10 BLK11 BLK12 BLK13
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
vmovdqu BLK4, 64(ARG3)
|
||||
vmovdqu BLK5, 80(ARG3)
|
||||
vmovdqu BLK6, 96(ARG3)
|
||||
vmovdqu BLK7, 112(ARG3)
|
||||
vmovdqu BLK8, 128(ARG3)
|
||||
vmovdqu BLK9, 144(ARG3)
|
||||
vmovdqu BLK10, 160(ARG3)
|
||||
vmovdqu BLK11, 176(ARG3)
|
||||
vmovdqu BLK12, 192(ARG3)
|
||||
vmovdqu BLK13, 208(ARG3)
|
||||
leaq 224(ARG2), ARG2
|
||||
leaq 224(ARG3), ARG3
|
||||
subl $224, ARG4
|
||||
cmpl $224, ARG4
|
||||
jb .ecb_aesdec_start
|
||||
jmp .ecb_aesdec_14_blks_loop
|
||||
|
||||
.align 16
|
||||
.ecb_dec_proc_8_blks:
|
||||
.aesecbdec_8_blks_loop:
|
||||
movq KEY, KTMP
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
vpxor 64(ARG2), RDK, BLK4
|
||||
vpxor 80(ARG2), RDK, BLK5
|
||||
vpxor 96(ARG2), RDK, BLK6
|
||||
vpxor 112(ARG2), RDK, BLK7
|
||||
decl ROUNDS
|
||||
AES_DEC_8_BLKS KTMP ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 BLK5 BLK6 BLK7
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
vmovdqu BLK4, 64(ARG3)
|
||||
vmovdqu BLK5, 80(ARG3)
|
||||
vmovdqu BLK6, 96(ARG3)
|
||||
vmovdqu BLK7, 112(ARG3)
|
||||
leaq 128(ARG2), ARG2
|
||||
leaq 128(ARG3), ARG3
|
||||
subl $128, ARG4
|
||||
cmpl $128, ARG4
|
||||
jb .ecb_aesdec_start
|
||||
jmp .aesecbdec_8_blks_loop
|
||||
|
||||
.align 16
|
||||
.ecb_dec_proc_1_blk:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
decl ROUNDS
|
||||
AES_DEC_1_BLK KEY ROUNDS RDK BLK0
|
||||
vmovdqu BLK0, (ARG3)
|
||||
jmp .Lecb_aesdec_finish
|
||||
|
||||
.align 16
|
||||
.ecb_dec_proc_2_blks:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
decl ROUNDS
|
||||
AES_DEC_2_BLKS KEY ROUNDS RDK BLK0 BLK1
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
jmp .Lecb_aesdec_finish
|
||||
|
||||
.align 16
|
||||
.ecb_dec_proc_3_blks:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
decl ROUNDS
|
||||
AES_DEC_3_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
jmp .Lecb_aesdec_finish
|
||||
|
||||
.align 16
|
||||
.ecb_dec_proc_4_blks:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
decl ROUNDS
|
||||
AES_DEC_4_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
jmp .Lecb_aesdec_finish
|
||||
|
||||
.align 16
|
||||
.ecb_dec_proc_5_blks:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
vpxor 64(ARG2), RDK, BLK4
|
||||
decl ROUNDS
|
||||
AES_DEC_5_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
vmovdqu BLK4, 64(ARG3)
|
||||
jmp .Lecb_aesdec_finish
|
||||
|
||||
.align 16
|
||||
.ecb_dec_proc_6_blks:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
vpxor 64(ARG2), RDK, BLK4
|
||||
vpxor 80(ARG2), RDK, BLK5
|
||||
decl ROUNDS
|
||||
AES_DEC_6_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 BLK5
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
vmovdqu BLK4, 64(ARG3)
|
||||
vmovdqu BLK5, 80(ARG3)
|
||||
jmp .Lecb_aesdec_finish
|
||||
|
||||
.align 16
|
||||
.ecb_dec_proc_7_blks:
|
||||
movl 240(KEY), ROUNDS
|
||||
vmovdqu (KEY), RDK
|
||||
vpxor (ARG2), RDK, BLK0
|
||||
vpxor 16(ARG2), RDK, BLK1
|
||||
vpxor 32(ARG2), RDK, BLK2
|
||||
vpxor 48(ARG2), RDK, BLK3
|
||||
vpxor 64(ARG2), RDK, BLK4
|
||||
vpxor 80(ARG2), RDK, BLK5
|
||||
vpxor 96(ARG2), RDK, BLK6
|
||||
decl ROUNDS
|
||||
AES_DEC_7_BLKS KEY ROUNDS RDK BLK0 BLK1 BLK2 BLK3 BLK4 BLK5 BLK6
|
||||
vmovdqu BLK0, (ARG3)
|
||||
vmovdqu BLK1, 16(ARG3)
|
||||
vmovdqu BLK2, 32(ARG3)
|
||||
vmovdqu BLK3, 48(ARG3)
|
||||
vmovdqu BLK4, 64(ARG3)
|
||||
vmovdqu BLK5, 80(ARG3)
|
||||
vmovdqu BLK6, 96(ARG3)
|
||||
|
||||
.align 16
|
||||
.Lecb_aesdec_finish:
|
||||
vpxor BLK0, BLK0, BLK0
|
||||
vpxor BLK1, BLK1, BLK1
|
||||
vpxor BLK2, BLK2, BLK2
|
||||
vpxor BLK3, BLK3, BLK3
|
||||
vpxor BLK4, BLK4, BLK4
|
||||
vpxor BLK5, BLK5, BLK5
|
||||
vpxor BLK6, BLK6, BLK6
|
||||
vpxor BLK7, BLK7, BLK7
|
||||
vpxor BLK8, BLK8, BLK8
|
||||
vpxor BLK9, BLK9, BLK9
|
||||
vpxor BLK10, BLK10, BLK10
|
||||
vpxor BLK11, BLK11, BLK11
|
||||
vpxor BLK12, BLK12, BLK12
|
||||
vpxor BLK13, BLK13, BLK13
|
||||
vpxor RDK, RDK, RDK
|
||||
movl $0, RET
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size CRYPT_AES_ECB_Decrypt, .-CRYPT_AES_ECB_Decrypt
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,951 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_CRYPTO_AES
|
||||
|
||||
.file "crypt_aes_macro_armv8.s"
|
||||
.text
|
||||
.arch armv8-a+crypto
|
||||
|
||||
BLK0 .req v0
|
||||
|
||||
/*
|
||||
* AES_ENC_1_BLKS
|
||||
*/
|
||||
.macro AES_ENC_1_BLK key blk rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.Loop_enc:
|
||||
aese \blk,\rdk0
|
||||
aesmc \blk,\blk
|
||||
subs \rounds,\rounds,#2
|
||||
ld1 {\rdk0s},[\key],#16
|
||||
aese \blk,\rdk1
|
||||
aesmc \blk,\blk
|
||||
ld1 {\rdk1s},[\key],#16
|
||||
b.gt .Loop_enc
|
||||
|
||||
aese \blk,\rdk0
|
||||
aesmc \blk,\blk
|
||||
ld1 {\rdk0s},[\key]
|
||||
aese \blk,\rdk1
|
||||
eor \blk,\blk,\rdk0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* AES_DEC_1_BLKS
|
||||
*/
|
||||
.macro AES_DEC_1_BLK key blk rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.Loop_dec:
|
||||
aesd \blk,\rdk0
|
||||
aesimc \blk,\blk
|
||||
subs \rounds,\rounds,#2
|
||||
ld1 {\rdk0s},[\key],#16
|
||||
aesd \blk,\rdk1
|
||||
aesimc \blk,\blk
|
||||
ld1 {\rdk1s},[\key],#16
|
||||
b.gt .Loop_dec
|
||||
|
||||
aesd \blk,\rdk0
|
||||
aesimc \blk,\blk
|
||||
ld1 {\rdk0s},[\key]
|
||||
aesd \blk,\rdk1
|
||||
eor \blk,\blk,\rdk0
|
||||
.endm
|
||||
|
||||
.macro SETDECKEY_LDR_9_BLOCK PTR
|
||||
ld1 {v1.4s}, [\PTR], #16
|
||||
ld1 {v2.4s}, [\PTR], #16
|
||||
ld1 {v3.4s}, [\PTR], #16
|
||||
ld1 {v4.4s}, [\PTR], #16
|
||||
ld1 {v5.4s}, [\PTR], #16
|
||||
ld1 {v6.4s}, [\PTR], #16
|
||||
ld1 {v7.4s}, [\PTR], #16
|
||||
ld1 {v8.4s}, [\PTR], #16
|
||||
ld1 {v9.4s}, [\PTR], #16
|
||||
.endm
|
||||
|
||||
.macro SETDECKEY_INVMIX_9_BLOCK
|
||||
aesimc v1.16b, v1.16b
|
||||
aesimc v2.16b, v2.16b
|
||||
aesimc v3.16b, v3.16b
|
||||
aesimc v4.16b, v4.16b
|
||||
aesimc v5.16b, v5.16b
|
||||
aesimc v6.16b, v6.16b
|
||||
aesimc v7.16b, v7.16b
|
||||
aesimc v8.16b, v8.16b
|
||||
aesimc v9.16b, v9.16b
|
||||
.endm
|
||||
|
||||
.macro SETDECKEY_STR_9_BLOCK PTR OFFSETREG
|
||||
st1 {v1.4s}, [\PTR], \OFFSETREG
|
||||
st1 {v2.4s}, [\PTR], \OFFSETREG
|
||||
st1 {v3.4s}, [\PTR], \OFFSETREG
|
||||
st1 {v4.4s}, [\PTR], \OFFSETREG
|
||||
st1 {v5.4s}, [\PTR], \OFFSETREG
|
||||
st1 {v6.4s}, [\PTR], \OFFSETREG
|
||||
st1 {v7.4s}, [\PTR], \OFFSETREG
|
||||
st1 {v8.4s}, [\PTR], \OFFSETREG
|
||||
st1 {v9.4s}, [\PTR], \OFFSETREG
|
||||
.endm
|
||||
|
||||
/*
|
||||
* AES_ENC_2_BLKS
|
||||
*/
|
||||
.macro AES_ENC_2_BLKS key blk0 blk1 rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.Loop_enc_2_blks:
|
||||
aese \blk0,\rdk0
|
||||
aesmc \blk0,\blk0
|
||||
aese \blk0,\rdk1
|
||||
aesmc \blk0,\blk0
|
||||
|
||||
aese \blk1,\rdk0
|
||||
aesmc \blk1,\blk1
|
||||
aese \blk1,\rdk1
|
||||
aesmc \blk1,\blk1
|
||||
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
subs \rounds,\rounds,#2
|
||||
b.gt .Loop_enc_2_blks
|
||||
|
||||
aese \blk0,\rdk0
|
||||
aesmc \blk0,\blk0
|
||||
aese \blk1,\rdk0
|
||||
aesmc \blk1,\blk1
|
||||
ld1 {\rdk0s},[\key]
|
||||
aese \blk0,\rdk1
|
||||
aese \blk1,\rdk1
|
||||
eor \blk0,\blk0,\rdk0
|
||||
eor \blk1,\blk1,\rdk0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* AES_ENC_3_BLKS
|
||||
*/
|
||||
.macro AES_ENC_3_BLKS key blk0 blk1 blk2 rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.align 3
|
||||
.Loop_enc_3_blks:
|
||||
aese \blk0,\rdk0
|
||||
aesmc \blk0,\blk0
|
||||
aese \blk0,\rdk1
|
||||
aesmc \blk0,\blk0
|
||||
|
||||
aese \blk1,\rdk0
|
||||
aesmc \blk1,\blk1
|
||||
aese \blk1,\rdk1
|
||||
aesmc \blk1,\blk1
|
||||
|
||||
aese \blk2,\rdk0
|
||||
aesmc \blk2,\blk2
|
||||
aese \blk2,\rdk1
|
||||
aesmc \blk2,\blk2
|
||||
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
subs \rounds,\rounds,#2
|
||||
b.gt .Loop_enc_3_blks
|
||||
|
||||
aese \blk0,\rdk0
|
||||
aesmc \blk0,\blk0
|
||||
aese \blk1,\rdk0
|
||||
aesmc \blk1,\blk1
|
||||
aese \blk2,\rdk0
|
||||
aesmc \blk2,\blk2
|
||||
ld1 {\rdk0s},[\key]
|
||||
aese \blk0,\rdk1
|
||||
aese \blk1,\rdk1
|
||||
aese \blk2,\rdk1
|
||||
eor \blk0,\blk0,\rdk0
|
||||
eor \blk1,\blk1,\rdk0
|
||||
eor \blk2,\blk2,\rdk0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* AES_ENC_4_BLKS
|
||||
*/
|
||||
.macro AES_ENC_4_BLKS key blk0 blk1 blk2 blk3 rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.Loop_enc_4_blks:
|
||||
aese \blk0,\rdk0
|
||||
aesmc \blk0,\blk0
|
||||
aese \blk0,\rdk1
|
||||
aesmc \blk0,\blk0
|
||||
|
||||
aese \blk1,\rdk0
|
||||
aesmc \blk1,\blk1
|
||||
aese \blk1,\rdk1
|
||||
aesmc \blk1,\blk1
|
||||
|
||||
aese \blk2,\rdk0
|
||||
aesmc \blk2,\blk2
|
||||
aese \blk2,\rdk1
|
||||
aesmc \blk2,\blk2
|
||||
|
||||
aese \blk3,\rdk0
|
||||
aesmc \blk3,\blk3
|
||||
aese \blk3,\rdk1
|
||||
aesmc \blk3,\blk3
|
||||
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
subs \rounds,\rounds,#2
|
||||
b.gt .Loop_enc_4_blks
|
||||
|
||||
aese \blk0,\rdk0
|
||||
aesmc \blk0,\blk0
|
||||
aese \blk1,\rdk0
|
||||
aesmc \blk1,\blk1
|
||||
aese \blk2,\rdk0
|
||||
aesmc \blk2,\blk2
|
||||
aese \blk3,\rdk0
|
||||
aesmc \blk3,\blk3
|
||||
ld1 {\rdk0s},[\key]
|
||||
aese \blk0,\rdk1
|
||||
aese \blk1,\rdk1
|
||||
aese \blk2,\rdk1
|
||||
aese \blk3,\rdk1
|
||||
eor \blk0,\blk0,\rdk0
|
||||
eor \blk1,\blk1,\rdk0
|
||||
eor \blk2,\blk2,\rdk0
|
||||
eor \blk3,\blk3,\rdk0
|
||||
.endm
|
||||
|
||||
|
||||
/*
|
||||
* AES_ENC_5_BLKS
|
||||
*/
|
||||
.macro AES_ENC_5_BLKS key blk0 blk1 blk2 blk3 blk4 rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.Loop_enc_5_blks:
|
||||
aese \blk0,\rdk0
|
||||
aesmc \blk0,\blk0
|
||||
aese \blk0,\rdk1
|
||||
aesmc \blk0,\blk0
|
||||
|
||||
aese \blk1,\rdk0
|
||||
aesmc \blk1,\blk1
|
||||
aese \blk1,\rdk1
|
||||
aesmc \blk1,\blk1
|
||||
|
||||
aese \blk2,\rdk0
|
||||
aesmc \blk2,\blk2
|
||||
aese \blk2,\rdk1
|
||||
aesmc \blk2,\blk2
|
||||
|
||||
aese \blk3,\rdk0
|
||||
aesmc \blk3,\blk3
|
||||
aese \blk3,\rdk1
|
||||
aesmc \blk3,\blk3
|
||||
|
||||
aese \blk4,\rdk0
|
||||
aesmc \blk4,\blk4
|
||||
aese \blk4,\rdk1
|
||||
aesmc \blk4,\blk4
|
||||
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
subs \rounds,\rounds,#2
|
||||
b.gt .Loop_enc_5_blks
|
||||
|
||||
aese \blk0,\rdk0
|
||||
aesmc \blk0,\blk0
|
||||
aese \blk1,\rdk0
|
||||
aesmc \blk1,\blk1
|
||||
aese \blk2,\rdk0
|
||||
aesmc \blk2,\blk2
|
||||
aese \blk3,\rdk0
|
||||
aesmc \blk3,\blk3
|
||||
aese \blk4,\rdk0
|
||||
aesmc \blk4,\blk4
|
||||
ld1 {\rdk0s},[\key]
|
||||
aese \blk0,\rdk1
|
||||
aese \blk1,\rdk1
|
||||
aese \blk2,\rdk1
|
||||
aese \blk3,\rdk1
|
||||
aese \blk4,\rdk1
|
||||
eor \blk0,\blk0,\rdk0
|
||||
eor \blk1,\blk1,\rdk0
|
||||
eor \blk2,\blk2,\rdk0
|
||||
eor \blk3,\blk3,\rdk0
|
||||
eor \blk4,\blk4,\rdk0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* AES_ENC_6_BLKS
|
||||
*/
|
||||
.macro AES_ENC_6_BLKS key blk0 blk1 blk2 blk3 blk4 blk5 rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.Loop_enc_6_blks:
|
||||
aese \blk0,\rdk0
|
||||
aesmc \blk0,\blk0
|
||||
aese \blk0,\rdk1
|
||||
aesmc \blk0,\blk0
|
||||
|
||||
aese \blk1,\rdk0
|
||||
aesmc \blk1,\blk1
|
||||
aese \blk1,\rdk1
|
||||
aesmc \blk1,\blk1
|
||||
|
||||
aese \blk2,\rdk0
|
||||
aesmc \blk2,\blk2
|
||||
aese \blk2,\rdk1
|
||||
aesmc \blk2,\blk2
|
||||
|
||||
aese \blk3,\rdk0
|
||||
aesmc \blk3,\blk3
|
||||
aese \blk3,\rdk1
|
||||
aesmc \blk3,\blk3
|
||||
|
||||
aese \blk4,\rdk0
|
||||
aesmc \blk4,\blk4
|
||||
aese \blk4,\rdk1
|
||||
aesmc \blk4,\blk4
|
||||
|
||||
aese \blk5,\rdk0
|
||||
aesmc \blk5,\blk5
|
||||
aese \blk5,\rdk1
|
||||
aesmc \blk5,\blk5
|
||||
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
subs \rounds,\rounds,#2
|
||||
b.gt .Loop_enc_6_blks
|
||||
|
||||
aese \blk0,\rdk0
|
||||
aesmc \blk0,\blk0
|
||||
aese \blk1,\rdk0
|
||||
aesmc \blk1,\blk1
|
||||
aese \blk2,\rdk0
|
||||
aesmc \blk2,\blk2
|
||||
aese \blk3,\rdk0
|
||||
aesmc \blk3,\blk3
|
||||
aese \blk4,\rdk0
|
||||
aesmc \blk4,\blk4
|
||||
aese \blk5,\rdk0
|
||||
aesmc \blk5,\blk5
|
||||
ld1 {\rdk0s},[\key]
|
||||
aese \blk0,\rdk1
|
||||
aese \blk1,\rdk1
|
||||
aese \blk2,\rdk1
|
||||
aese \blk3,\rdk1
|
||||
aese \blk4,\rdk1
|
||||
aese \blk5,\rdk1
|
||||
eor \blk0,\blk0,\rdk0
|
||||
eor \blk1,\blk1,\rdk0
|
||||
eor \blk2,\blk2,\rdk0
|
||||
eor \blk3,\blk3,\rdk0
|
||||
eor \blk4,\blk4,\rdk0
|
||||
eor \blk5,\blk5,\rdk0
|
||||
.endm
|
||||
|
||||
|
||||
/*
|
||||
* AES_ENC_7_BLKS
|
||||
*/
|
||||
.macro AES_ENC_7_BLKS key blk0 blk1 blk2 blk3 blk4 blk5 blk6 rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.Loop_enc_7_blks:
|
||||
aese \blk0,\rdk0
|
||||
aesmc \blk0,\blk0
|
||||
aese \blk0,\rdk1
|
||||
aesmc \blk0,\blk0
|
||||
|
||||
aese \blk1,\rdk0
|
||||
aesmc \blk1,\blk1
|
||||
aese \blk1,\rdk1
|
||||
aesmc \blk1,\blk1
|
||||
|
||||
aese \blk2,\rdk0
|
||||
aesmc \blk2,\blk2
|
||||
aese \blk2,\rdk1
|
||||
aesmc \blk2,\blk2
|
||||
|
||||
aese \blk3,\rdk0
|
||||
aesmc \blk3,\blk3
|
||||
aese \blk3,\rdk1
|
||||
aesmc \blk3,\blk3
|
||||
|
||||
aese \blk4,\rdk0
|
||||
aesmc \blk4,\blk4
|
||||
aese \blk4,\rdk1
|
||||
aesmc \blk4,\blk4
|
||||
|
||||
aese \blk5,\rdk0
|
||||
aesmc \blk5,\blk5
|
||||
aese \blk5,\rdk1
|
||||
aesmc \blk5,\blk5
|
||||
|
||||
aese \blk6,\rdk0
|
||||
aesmc \blk6,\blk6
|
||||
aese \blk6,\rdk1
|
||||
aesmc \blk6,\blk6
|
||||
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
subs \rounds,\rounds,#2
|
||||
b.gt .Loop_enc_7_blks
|
||||
|
||||
aese \blk0,\rdk0
|
||||
aesmc \blk0,\blk0
|
||||
aese \blk1,\rdk0
|
||||
aesmc \blk1,\blk1
|
||||
aese \blk2,\rdk0
|
||||
aesmc \blk2,\blk2
|
||||
aese \blk3,\rdk0
|
||||
aesmc \blk3,\blk3
|
||||
aese \blk4,\rdk0
|
||||
aesmc \blk4,\blk4
|
||||
aese \blk5,\rdk0
|
||||
aesmc \blk5,\blk5
|
||||
aese \blk6,\rdk0
|
||||
aesmc \blk6,\blk6
|
||||
ld1 {\rdk0s},[\key]
|
||||
aese \blk0,\rdk1
|
||||
aese \blk1,\rdk1
|
||||
aese \blk2,\rdk1
|
||||
aese \blk3,\rdk1
|
||||
aese \blk4,\rdk1
|
||||
aese \blk5,\rdk1
|
||||
aese \blk6,\rdk1
|
||||
eor \blk0,\blk0,\rdk0
|
||||
eor \blk1,\blk1,\rdk0
|
||||
eor \blk2,\blk2,\rdk0
|
||||
eor \blk3,\blk3,\rdk0
|
||||
eor \blk4,\blk4,\rdk0
|
||||
eor \blk5,\blk5,\rdk0
|
||||
eor \blk6,\blk6,\rdk0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* AES_ENC_8_BLKS
|
||||
*/
|
||||
.macro AES_ENC_8_BLKS key blk0 blk1 blk2 blk3 blk4 blk5 blk6 blk7 rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.Loop_enc_8_blks:
|
||||
aese \blk0,\rdk0
|
||||
aesmc \blk0,\blk0
|
||||
aese \blk0,\rdk1
|
||||
aesmc \blk0,\blk0
|
||||
|
||||
aese \blk1,\rdk0
|
||||
aesmc \blk1,\blk1
|
||||
aese \blk1,\rdk1
|
||||
aesmc \blk1,\blk1
|
||||
|
||||
aese \blk2,\rdk0
|
||||
aesmc \blk2,\blk2
|
||||
aese \blk2,\rdk1
|
||||
aesmc \blk2,\blk2
|
||||
|
||||
aese \blk3,\rdk0
|
||||
aesmc \blk3,\blk3
|
||||
aese \blk3,\rdk1
|
||||
aesmc \blk3,\blk3
|
||||
|
||||
aese \blk4,\rdk0
|
||||
aesmc \blk4,\blk4
|
||||
aese \blk4,\rdk1
|
||||
aesmc \blk4,\blk4
|
||||
|
||||
aese \blk5,\rdk0
|
||||
aesmc \blk5,\blk5
|
||||
aese \blk5,\rdk1
|
||||
aesmc \blk5,\blk5
|
||||
|
||||
aese \blk6,\rdk0
|
||||
aesmc \blk6,\blk6
|
||||
aese \blk6,\rdk1
|
||||
aesmc \blk6,\blk6
|
||||
|
||||
aese \blk7,\rdk0
|
||||
aesmc \blk7,\blk7
|
||||
aese \blk7,\rdk1
|
||||
aesmc \blk7,\blk7
|
||||
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
subs \rounds,\rounds,#2
|
||||
b.gt .Loop_enc_8_blks
|
||||
|
||||
|
||||
aese \blk0,\rdk0
|
||||
aesmc \blk0,\blk0
|
||||
aese \blk1,\rdk0
|
||||
aesmc \blk1,\blk1
|
||||
aese \blk2,\rdk0
|
||||
aesmc \blk2,\blk2
|
||||
aese \blk3,\rdk0
|
||||
aesmc \blk3,\blk3
|
||||
aese \blk4,\rdk0
|
||||
aesmc \blk4,\blk4
|
||||
aese \blk5,\rdk0
|
||||
aesmc \blk5,\blk5
|
||||
aese \blk6,\rdk0
|
||||
aesmc \blk6,\blk6
|
||||
aese \blk7,\rdk0
|
||||
aesmc \blk7,\blk7
|
||||
ld1 {\rdk0s},[\key]
|
||||
aese \blk0,\rdk1
|
||||
aese \blk1,\rdk1
|
||||
aese \blk2,\rdk1
|
||||
aese \blk3,\rdk1
|
||||
aese \blk4,\rdk1
|
||||
aese \blk5,\rdk1
|
||||
aese \blk6,\rdk1
|
||||
aese \blk7,\rdk1
|
||||
eor \blk0,\blk0,\rdk0
|
||||
eor \blk1,\blk1,\rdk0
|
||||
eor \blk2,\blk2,\rdk0
|
||||
eor \blk3,\blk3,\rdk0
|
||||
eor \blk4,\blk4,\rdk0
|
||||
eor \blk5,\blk5,\rdk0
|
||||
eor \blk6,\blk6,\rdk0
|
||||
eor \blk7,\blk7,\rdk0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* AES_DEC_2_BLKS
|
||||
*/
|
||||
.macro AES_DEC_2_BLKS key blk0 blk1 rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.Loop_dec_2_blks:
|
||||
aesd \blk0,\rdk0
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk0,\rdk1
|
||||
aesimc \blk0,\blk0
|
||||
|
||||
aesd \blk1,\rdk0
|
||||
aesimc \blk1,\blk1
|
||||
aesd \blk1,\rdk1
|
||||
aesimc \blk1,\blk1
|
||||
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
subs \rounds,\rounds,#2
|
||||
b.gt .Loop_dec_2_blks
|
||||
|
||||
|
||||
aesd \blk0,\rdk0
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk1,\rdk0
|
||||
aesimc \blk1,\blk1
|
||||
ld1 {\rdk0s},[\key]
|
||||
aesd \blk0,\rdk1
|
||||
aesd \blk1,\rdk1
|
||||
eor \blk0,\blk0,\rdk0
|
||||
eor \blk1,\blk1,\rdk0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* AES_DEC_3_BLKS
|
||||
*/
|
||||
.macro AES_DEC_3_BLKS key blk0 blk1 blk2 rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.align 3
|
||||
.Loop_dec_3_blks:
|
||||
aesd \blk0,\rdk0
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk0,\rdk1
|
||||
aesimc \blk0,\blk0
|
||||
|
||||
aesd \blk1,\rdk0
|
||||
aesimc \blk1,\blk1
|
||||
aesd \blk1,\rdk1
|
||||
aesimc \blk1,\blk1
|
||||
|
||||
aesd \blk2,\rdk0
|
||||
aesimc \blk2,\blk2
|
||||
aesd \blk2,\rdk1
|
||||
aesimc \blk2,\blk2
|
||||
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
subs \rounds,\rounds,#2
|
||||
b.gt .Loop_dec_3_blks
|
||||
|
||||
aesd \blk0,\rdk0
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk1,\rdk0
|
||||
aesimc \blk1,\blk1
|
||||
aesd \blk2,\rdk0
|
||||
aesimc \blk2,\blk2
|
||||
ld1 {\rdk0s},[\key]
|
||||
aesd \blk0,\rdk1
|
||||
aesd \blk1,\rdk1
|
||||
aesd \blk2,\rdk1
|
||||
eor \blk0,\blk0,\rdk0
|
||||
eor \blk1,\blk1,\rdk0
|
||||
eor \blk2,\blk2,\rdk0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* AES_DEC_4_BLKS
|
||||
*/
|
||||
.macro AES_DEC_4_BLKS key blk0 blk1 blk2 blk3 rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.Loop_dec_4_blks:
|
||||
aesd \blk0,\rdk0
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk0,\rdk1
|
||||
aesimc \blk0,\blk0
|
||||
|
||||
aesd \blk1,\rdk0
|
||||
aesimc \blk1,\blk1
|
||||
aesd \blk1,\rdk1
|
||||
aesimc \blk1,\blk1
|
||||
|
||||
aesd \blk2,\rdk0
|
||||
aesimc \blk2,\blk2
|
||||
aesd \blk2,\rdk1
|
||||
aesimc \blk2,\blk2
|
||||
|
||||
aesd \blk3,\rdk0
|
||||
aesimc \blk3,\blk3
|
||||
aesd \blk3,\rdk1
|
||||
aesimc \blk3,\blk3
|
||||
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
subs \rounds,\rounds,#2
|
||||
b.gt .Loop_dec_4_blks
|
||||
|
||||
aesd \blk0,\rdk0
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk1,\rdk0
|
||||
aesimc \blk1,\blk1
|
||||
aesd \blk2,\rdk0
|
||||
aesimc \blk2,\blk2
|
||||
aesd \blk3,\rdk0
|
||||
aesimc \blk3,\blk3
|
||||
ld1 {\rdk0s},[\key]
|
||||
aesd \blk0,\rdk1
|
||||
aesd \blk1,\rdk1
|
||||
aesd \blk2,\rdk1
|
||||
aesd \blk3,\rdk1
|
||||
eor \blk0,\blk0,\rdk0
|
||||
eor \blk1,\blk1,\rdk0
|
||||
eor \blk2,\blk2,\rdk0
|
||||
eor \blk3,\blk3,\rdk0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* AES_DEC_5_BLKS
|
||||
*/
|
||||
.macro AES_DEC_5_BLKS key blk0 blk1 blk2 blk3 blk4 rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.Loop_dec_5_blks:
|
||||
aesd \blk0,\rdk0
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk0,\rdk1
|
||||
aesimc \blk0,\blk0
|
||||
|
||||
aesd \blk1,\rdk0
|
||||
aesimc \blk1,\blk1
|
||||
aesd \blk1,\rdk1
|
||||
aesimc \blk1,\blk1
|
||||
|
||||
aesd \blk2,\rdk0
|
||||
aesimc \blk2,\blk2
|
||||
aesd \blk2,\rdk1
|
||||
aesimc \blk2,\blk2
|
||||
|
||||
aesd \blk3,\rdk0
|
||||
aesimc \blk3,\blk3
|
||||
aesd \blk3,\rdk1
|
||||
aesimc \blk3,\blk3
|
||||
|
||||
aesd \blk4,\rdk0
|
||||
aesimc \blk4,\blk4
|
||||
aesd \blk4,\rdk1
|
||||
aesimc \blk4,\blk4
|
||||
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
subs \rounds,\rounds,#2
|
||||
b.gt .Loop_dec_5_blks
|
||||
|
||||
aesd \blk0,\rdk0
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk1,\rdk0
|
||||
aesimc \blk1,\blk1
|
||||
aesd \blk2,\rdk0
|
||||
aesimc \blk2,\blk2
|
||||
aesd \blk3,\rdk0
|
||||
aesimc \blk3,\blk3
|
||||
aesd \blk4,\rdk0
|
||||
aesimc \blk4,\blk4
|
||||
ld1 {\rdk0s},[\key]
|
||||
aesd \blk0,\rdk1
|
||||
aesd \blk1,\rdk1
|
||||
aesd \blk2,\rdk1
|
||||
aesd \blk3,\rdk1
|
||||
aesd \blk4,\rdk1
|
||||
eor \blk0,\blk0,\rdk0
|
||||
eor \blk1,\blk1,\rdk0
|
||||
eor \blk2,\blk2,\rdk0
|
||||
eor \blk3,\blk3,\rdk0
|
||||
eor \blk4,\blk4,\rdk0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* AES_DEC_6_BLKS
|
||||
*/
|
||||
.macro AES_DEC_6_BLKS key blk0 blk1 blk2 blk3 blk4 blk5 rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.Loop_dec_6_blks:
|
||||
aesd \blk0,\rdk0
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk0,\rdk1
|
||||
aesimc \blk0,\blk0
|
||||
|
||||
aesd \blk1,\rdk0
|
||||
aesimc \blk1,\blk1
|
||||
aesd \blk1,\rdk1
|
||||
aesimc \blk1,\blk1
|
||||
|
||||
aesd \blk2,\rdk0
|
||||
aesimc \blk2,\blk2
|
||||
aesd \blk2,\rdk1
|
||||
aesimc \blk2,\blk2
|
||||
|
||||
aesd \blk3,\rdk0
|
||||
aesimc \blk3,\blk3
|
||||
aesd \blk3,\rdk1
|
||||
aesimc \blk3,\blk3
|
||||
|
||||
aesd \blk4,\rdk0
|
||||
aesimc \blk4,\blk4
|
||||
aesd \blk4,\rdk1
|
||||
aesimc \blk4,\blk4
|
||||
|
||||
aesd \blk5,\rdk0
|
||||
aesimc \blk5,\blk5
|
||||
aesd \blk5,\rdk1
|
||||
aesimc \blk5,\blk5
|
||||
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
subs \rounds,\rounds,#2
|
||||
b.gt .Loop_dec_6_blks
|
||||
|
||||
aesd \blk0,\rdk0
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk1,\rdk0
|
||||
aesimc \blk1,\blk1
|
||||
aesd \blk2,\rdk0
|
||||
aesimc \blk2,\blk2
|
||||
aesd \blk3,\rdk0
|
||||
aesimc \blk3,\blk3
|
||||
aesd \blk4,\rdk0
|
||||
aesimc \blk4,\blk4
|
||||
aesd \blk5,\rdk0
|
||||
aesimc \blk5,\blk5
|
||||
ld1 {\rdk0s},[\key]
|
||||
aesd \blk0,\rdk1
|
||||
aesd \blk1,\rdk1
|
||||
aesd \blk2,\rdk1
|
||||
aesd \blk3,\rdk1
|
||||
aesd \blk4,\rdk1
|
||||
aesd \blk5,\rdk1
|
||||
eor \blk0,\blk0,\rdk0
|
||||
eor \blk1,\blk1,\rdk0
|
||||
eor \blk2,\blk2,\rdk0
|
||||
eor \blk3,\blk3,\rdk0
|
||||
eor \blk4,\blk4,\rdk0
|
||||
eor \blk5,\blk5,\rdk0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* AES_DEC_7_BLKS
|
||||
*/
|
||||
.macro AES_DEC_7_BLKS key blk0 blk1 blk2 blk3 blk4 blk5 blk6 rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.Loop_dec_7_blks:
|
||||
aesd \blk0,\rdk0
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk0,\rdk1
|
||||
aesimc \blk0,\blk0
|
||||
|
||||
aesd \blk1,\rdk0
|
||||
aesimc \blk1,\blk1
|
||||
aesd \blk1,\rdk1
|
||||
aesimc \blk1,\blk1
|
||||
|
||||
aesd \blk2,\rdk0
|
||||
aesimc \blk2,\blk2
|
||||
aesd \blk2,\rdk1
|
||||
aesimc \blk2,\blk2
|
||||
|
||||
aesd \blk3,\rdk0
|
||||
aesimc \blk3,\blk3
|
||||
aesd \blk3,\rdk1
|
||||
aesimc \blk3,\blk3
|
||||
|
||||
aesd \blk4,\rdk0
|
||||
aesimc \blk4,\blk4
|
||||
aesd \blk4,\rdk1
|
||||
aesimc \blk4,\blk4
|
||||
|
||||
aesd \blk5,\rdk0
|
||||
aesimc \blk5,\blk5
|
||||
aesd \blk5,\rdk1
|
||||
aesimc \blk5,\blk5
|
||||
|
||||
aesd \blk6,\rdk0
|
||||
aesimc \blk6,\blk6
|
||||
aesd \blk6,\rdk1
|
||||
aesimc \blk6,\blk6
|
||||
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
subs \rounds,\rounds,#2
|
||||
b.gt .Loop_dec_7_blks
|
||||
|
||||
aesd \blk0,\rdk0
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk1,\rdk0
|
||||
aesimc \blk1,\blk1
|
||||
aesd \blk2,\rdk0
|
||||
aesimc \blk2,\blk2
|
||||
aesd \blk3,\rdk0
|
||||
aesimc \blk3,\blk3
|
||||
aesd \blk4,\rdk0
|
||||
aesimc \blk4,\blk4
|
||||
aesd \blk5,\rdk0
|
||||
aesimc \blk5,\blk5
|
||||
aesd \blk6,\rdk0
|
||||
aesimc \blk6,\blk6
|
||||
ld1 {\rdk0s},[\key]
|
||||
aesd \blk0,\rdk1
|
||||
aesd \blk1,\rdk1
|
||||
aesd \blk2,\rdk1
|
||||
aesd \blk3,\rdk1
|
||||
aesd \blk4,\rdk1
|
||||
aesd \blk5,\rdk1
|
||||
aesd \blk6,\rdk1
|
||||
eor \blk0,\blk0,\rdk0
|
||||
eor \blk1,\blk1,\rdk0
|
||||
eor \blk2,\blk2,\rdk0
|
||||
eor \blk3,\blk3,\rdk0
|
||||
eor \blk4,\blk4,\rdk0
|
||||
eor \blk5,\blk5,\rdk0
|
||||
eor \blk6,\blk6,\rdk0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* AES_DEC_8_BLKS
|
||||
*/
|
||||
.macro AES_DEC_8_BLKS key blk0 blk1 blk2 blk3 blk4 blk5 blk6 blk7 rdk0s rdk1s rdk0 rdk1 rounds
|
||||
ldr \rounds,[\key,#240]
|
||||
ld1 {\rdk0s,\rdk1s},[\key],#32
|
||||
sub \rounds,\rounds,#2
|
||||
.align 5
|
||||
.Loop_dec_8_blks:
|
||||
aesd \blk0,\rdk0
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk5,\rdk0
|
||||
aesimc \blk5,\blk5
|
||||
aesd \blk1,\rdk0
|
||||
aesimc \blk1,\blk1
|
||||
aesd \blk6,\rdk0
|
||||
aesimc \blk6,\blk6
|
||||
aesd \blk2,\rdk0
|
||||
aesimc \blk2,\blk2
|
||||
aesd \blk3,\rdk0
|
||||
aesimc \blk3,\blk3
|
||||
aesd \blk4,\rdk0
|
||||
aesimc \blk4,\blk4
|
||||
aesd \blk7,\rdk0
|
||||
aesimc \blk7,\blk7
|
||||
|
||||
aesd \blk0,\rdk1
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk5,\rdk1
|
||||
aesimc \blk5,\blk5
|
||||
aesd \blk1,\rdk1
|
||||
aesimc \blk1,\blk1
|
||||
aesd \blk6,\rdk1
|
||||
aesimc \blk6,\blk6
|
||||
aesd \blk2,\rdk1
|
||||
aesimc \blk2,\blk2
|
||||
aesd \blk3,\rdk1
|
||||
aesimc \blk3,\blk3
|
||||
aesd \blk4,\rdk1
|
||||
aesimc \blk4,\blk4
|
||||
aesd \blk7,\rdk1
|
||||
ld1 {\rdk0s, \rdk1s},[\key],#32
|
||||
aesimc \blk7,\blk7
|
||||
|
||||
subs \rounds,\rounds,#2
|
||||
b.gt .Loop_dec_8_blks
|
||||
|
||||
aesd \blk0,\rdk0
|
||||
aesimc \blk0,\blk0
|
||||
aesd \blk1,\rdk0
|
||||
aesimc \blk1,\blk1
|
||||
aesd \blk2,\rdk0
|
||||
aesimc \blk2,\blk2
|
||||
aesd \blk3,\rdk0
|
||||
aesimc \blk3,\blk3
|
||||
aesd \blk4,\rdk0
|
||||
aesimc \blk4,\blk4
|
||||
aesd \blk5,\rdk0
|
||||
aesimc \blk5,\blk5
|
||||
aesd \blk6,\rdk0
|
||||
aesimc \blk6,\blk6
|
||||
aesd \blk7,\rdk0
|
||||
ld1 {\rdk0s},[\key]
|
||||
aesimc \blk7,\blk7
|
||||
|
||||
aesd \blk0,\rdk1
|
||||
aesd \blk1,\rdk1
|
||||
aesd \blk2,\rdk1
|
||||
aesd \blk3,\rdk1
|
||||
aesd \blk4,\rdk1
|
||||
aesd \blk5,\rdk1
|
||||
aesd \blk6,\rdk1
|
||||
aesd \blk7,\rdk1
|
||||
eor \blk0,\blk0,\rdk0
|
||||
eor \blk1,\blk1,\rdk0
|
||||
eor \blk2,\blk2,\rdk0
|
||||
eor \blk3,\blk3,\rdk0
|
||||
eor \blk4,\blk4,\rdk0
|
||||
eor \blk5,\blk5,\rdk0
|
||||
eor \blk6,\blk6,\rdk0
|
||||
eor \blk7,\blk7,\rdk0
|
||||
.endm
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,438 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_CRYPTO_AES
|
||||
|
||||
.file "crypt_aes_macro_x86_64.s"
|
||||
|
||||
/* AES_ENC_1_BLK */
|
||||
.macro AES_ENC_1_BLK key round rdk blk
|
||||
.align 16
|
||||
.aesenc_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenc \rdk, \blk
|
||||
decl \round
|
||||
jnz .aesenc_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenclast \rdk, \blk
|
||||
.endm
|
||||
|
||||
/* AES_ENC_2_BLKS */
|
||||
.macro AES_ENC_2_BLKS key round rdk blk0 blk1
|
||||
.align 16
|
||||
.aesenc_2_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenc \rdk, \blk0
|
||||
aesenc \rdk, \blk1
|
||||
decl \round
|
||||
jnz .aesenc_2_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenclast \rdk, \blk0
|
||||
aesenclast \rdk, \blk1
|
||||
.endm
|
||||
|
||||
/* AES_ENC_3_BLKS */
|
||||
.macro AES_ENC_3_BLKS key round rdk blk0 blk1 blk2
|
||||
.align 16
|
||||
.aesenc_3_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenc \rdk, \blk0
|
||||
aesenc \rdk, \blk1
|
||||
aesenc \rdk, \blk2
|
||||
decl \round
|
||||
jnz .aesenc_3_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenclast \rdk, \blk0
|
||||
aesenclast \rdk, \blk1
|
||||
aesenclast \rdk, \blk2
|
||||
.endm
|
||||
|
||||
/* AES_ENC_4_BLKS */
|
||||
.macro AES_ENC_4_BLKS key round rdk blk0 blk1 blk2 blk3
|
||||
.align 16
|
||||
.aesenc_4_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenc \rdk, \blk0
|
||||
aesenc \rdk, \blk1
|
||||
aesenc \rdk, \blk2
|
||||
aesenc \rdk, \blk3
|
||||
decl \round
|
||||
jnz .aesenc_4_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenclast \rdk, \blk0
|
||||
aesenclast \rdk, \blk1
|
||||
aesenclast \rdk, \blk2
|
||||
aesenclast \rdk, \blk3
|
||||
.endm
|
||||
|
||||
/* AES_ENC_5_BLKS */
|
||||
.macro AES_ENC_5_BLKS key round rdk blk0 blk1 blk2 blk3 blk4
|
||||
.align 16
|
||||
.aesenc_5_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenc \rdk, \blk0
|
||||
aesenc \rdk, \blk1
|
||||
aesenc \rdk, \blk2
|
||||
aesenc \rdk, \blk3
|
||||
aesenc \rdk, \blk4
|
||||
decl \round
|
||||
jnz .aesenc_5_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenclast \rdk, \blk0
|
||||
aesenclast \rdk, \blk1
|
||||
aesenclast \rdk, \blk2
|
||||
aesenclast \rdk, \blk3
|
||||
aesenclast \rdk, \blk4
|
||||
.endm
|
||||
|
||||
/* AES_ENC_6_BLKS */
|
||||
.macro AES_ENC_6_BLKS key round rdk blk0 blk1 blk2 blk3 blk4 blk5
|
||||
.align 16
|
||||
.aesenc_6_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenc \rdk, \blk0
|
||||
aesenc \rdk, \blk1
|
||||
aesenc \rdk, \blk2
|
||||
aesenc \rdk, \blk3
|
||||
aesenc \rdk, \blk4
|
||||
aesenc \rdk, \blk5
|
||||
decl \round
|
||||
jnz .aesenc_6_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenclast \rdk, \blk0
|
||||
aesenclast \rdk, \blk1
|
||||
aesenclast \rdk, \blk2
|
||||
aesenclast \rdk, \blk3
|
||||
aesenclast \rdk, \blk4
|
||||
aesenclast \rdk, \blk5
|
||||
.endm
|
||||
|
||||
/* AES_ENC_7_BLKS */
|
||||
.macro AES_ENC_7_BLKS key round rdk blk0 blk1 blk2 blk3 blk4 blk5 blk6
|
||||
.align 16
|
||||
.aesenc_7_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenc \rdk, \blk0
|
||||
aesenc \rdk, \blk1
|
||||
aesenc \rdk, \blk2
|
||||
aesenc \rdk, \blk3
|
||||
aesenc \rdk, \blk4
|
||||
aesenc \rdk, \blk5
|
||||
aesenc \rdk, \blk6
|
||||
decl \round
|
||||
jnz .aesenc_7_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenclast \rdk, \blk0
|
||||
aesenclast \rdk, \blk1
|
||||
aesenclast \rdk, \blk2
|
||||
aesenclast \rdk, \blk3
|
||||
aesenclast \rdk, \blk4
|
||||
aesenclast \rdk, \blk5
|
||||
aesenclast \rdk, \blk6
|
||||
.endm
|
||||
|
||||
/* AES_ENC_8_BLKS */
|
||||
.macro AES_ENC_8_BLKS key round rdk blk0 blk1 blk2 blk3 blk4 blk5 blk6 blk7
|
||||
.align 16
|
||||
.aesenc_8_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenc \rdk, \blk0
|
||||
aesenc \rdk, \blk1
|
||||
aesenc \rdk, \blk2
|
||||
aesenc \rdk, \blk3
|
||||
aesenc \rdk, \blk4
|
||||
aesenc \rdk, \blk5
|
||||
aesenc \rdk, \blk6
|
||||
aesenc \rdk, \blk7
|
||||
decl \round
|
||||
jnz .aesenc_8_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenclast \rdk, \blk0
|
||||
aesenclast \rdk, \blk1
|
||||
aesenclast \rdk, \blk2
|
||||
aesenclast \rdk, \blk3
|
||||
aesenclast \rdk, \blk4
|
||||
aesenclast \rdk, \blk5
|
||||
aesenclast \rdk, \blk6
|
||||
aesenclast \rdk, \blk7
|
||||
.endm
|
||||
|
||||
/* AES_ENC_14_BLKS */
|
||||
.macro AES_ENC_14_BLKS ARG2 key round rdk blk0 blk1 blk2 blk3 blk4 blk5 blk6 blk7 blk8 blk9 blk10 blk11 blk12 blk13
|
||||
.align 16
|
||||
.aesenc_14_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenc \rdk, \blk0
|
||||
aesenc \rdk, \blk1
|
||||
aesenc \rdk, \blk2
|
||||
aesenc \rdk, \blk3
|
||||
aesenc \rdk, \blk4
|
||||
aesenc \rdk, \blk5
|
||||
aesenc \rdk, \blk6
|
||||
aesenc \rdk, \blk7
|
||||
aesenc \rdk, \blk8
|
||||
aesenc \rdk, \blk9
|
||||
aesenc \rdk, \blk10
|
||||
aesenc \rdk, \blk11
|
||||
aesenc \rdk, \blk12
|
||||
aesenc \rdk, \blk13
|
||||
decl \round
|
||||
jnz .aesenc_14_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesenclast \rdk, \blk0
|
||||
aesenclast \rdk, \blk1
|
||||
aesenclast \rdk, \blk2
|
||||
aesenclast \rdk, \blk3
|
||||
aesenclast \rdk, \blk4
|
||||
aesenclast \rdk, \blk5
|
||||
aesenclast \rdk, \blk6
|
||||
aesenclast \rdk, \blk7
|
||||
aesenclast \rdk, \blk8
|
||||
aesenclast \rdk, \blk9
|
||||
aesenclast \rdk, \blk10
|
||||
aesenclast \rdk, \blk11
|
||||
aesenclast \rdk, \blk12
|
||||
aesenclast \rdk, \blk13
|
||||
.endm
|
||||
|
||||
/* AES_DEC_1_BLK */
|
||||
.macro AES_DEC_1_BLK key round rdk blk
|
||||
.align 16
|
||||
.aesdec_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdec \rdk, \blk
|
||||
decl \round
|
||||
jnz .aesdec_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdeclast \rdk, \blk
|
||||
.endm
|
||||
|
||||
/* AES_DEC_2_BLKS */
|
||||
.macro AES_DEC_2_BLKS key round rdk blk0 blk1
|
||||
.align 32
|
||||
.aesdec_2_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdec \rdk, \blk0
|
||||
aesdec \rdk, \blk1
|
||||
decl \round
|
||||
jnz .aesdec_2_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdeclast \rdk, \blk0
|
||||
aesdeclast \rdk, \blk1
|
||||
.endm
|
||||
|
||||
/* AES_DEC_3_BLKS */
|
||||
.macro AES_DEC_3_BLKS key round rdk blk0 blk1 blk2
|
||||
.align 16
|
||||
.aesdec_3_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdec \rdk, \blk0
|
||||
aesdec \rdk, \blk1
|
||||
aesdec \rdk, \blk2
|
||||
decl \round
|
||||
jnz .aesdec_3_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdeclast \rdk, \blk0
|
||||
aesdeclast \rdk, \blk1
|
||||
aesdeclast \rdk, \blk2
|
||||
.endm
|
||||
|
||||
/* AES_DEC_4_BLKS */
|
||||
.macro AES_DEC_4_BLKS key round rdk blk0 blk1 blk2 blk3
|
||||
.align 16
|
||||
.aesdec_4_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdec \rdk, \blk0
|
||||
aesdec \rdk, \blk1
|
||||
aesdec \rdk, \blk2
|
||||
aesdec \rdk, \blk3
|
||||
decl \round
|
||||
jnz .aesdec_4_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdeclast \rdk, \blk0
|
||||
aesdeclast \rdk, \blk1
|
||||
aesdeclast \rdk, \blk2
|
||||
aesdeclast \rdk, \blk3
|
||||
.endm
|
||||
|
||||
/* AES_DEC_5_BLKS */
|
||||
.macro AES_DEC_5_BLKS key round rdk blk0 blk1 blk2 blk3 blk4
|
||||
.align 16
|
||||
.aesdec_5_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdec \rdk, \blk0
|
||||
aesdec \rdk, \blk1
|
||||
aesdec \rdk, \blk2
|
||||
aesdec \rdk, \blk3
|
||||
aesdec \rdk, \blk4
|
||||
decl \round
|
||||
jnz .aesdec_5_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdeclast \rdk, \blk0
|
||||
aesdeclast \rdk, \blk1
|
||||
aesdeclast \rdk, \blk2
|
||||
aesdeclast \rdk, \blk3
|
||||
aesdeclast \rdk, \blk4
|
||||
.endm
|
||||
|
||||
/* AES_DEC_6_BLKS */
|
||||
.macro AES_DEC_6_BLKS key round rdk blk0 blk1 blk2 blk3 blk4 blk5
|
||||
.align 16
|
||||
.aesdec_6_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdec \rdk, \blk0
|
||||
aesdec \rdk, \blk1
|
||||
aesdec \rdk, \blk2
|
||||
aesdec \rdk, \blk3
|
||||
aesdec \rdk, \blk4
|
||||
aesdec \rdk, \blk5
|
||||
decl \round
|
||||
jnz .aesdec_6_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdeclast \rdk, \blk0
|
||||
aesdeclast \rdk, \blk1
|
||||
aesdeclast \rdk, \blk2
|
||||
aesdeclast \rdk, \blk3
|
||||
aesdeclast \rdk, \blk4
|
||||
aesdeclast \rdk, \blk5
|
||||
.endm
|
||||
|
||||
/* AES_DEC_7_BLKS */
|
||||
.macro AES_DEC_7_BLKS key round rdk blk0 blk1 blk2 blk3 blk4 blk5 blk6
|
||||
.align 16
|
||||
.aesdec_7_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdec \rdk, \blk0
|
||||
aesdec \rdk, \blk1
|
||||
aesdec \rdk, \blk2
|
||||
aesdec \rdk, \blk3
|
||||
aesdec \rdk, \blk4
|
||||
aesdec \rdk, \blk5
|
||||
aesdec \rdk, \blk6
|
||||
decl \round
|
||||
jnz .aesdec_7_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdeclast \rdk, \blk0
|
||||
aesdeclast \rdk, \blk1
|
||||
aesdeclast \rdk, \blk2
|
||||
aesdeclast \rdk, \blk3
|
||||
aesdeclast \rdk, \blk4
|
||||
aesdeclast \rdk, \blk5
|
||||
aesdeclast \rdk, \blk6
|
||||
.endm
|
||||
|
||||
/* AES_DEC_8_BLKS */
|
||||
.macro AES_DEC_8_BLKS key round rdk blk0 blk1 blk2 blk3 blk4 blk5 blk6 blk7
|
||||
|
||||
.align 16
|
||||
.aesdec_8_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdec \rdk, \blk0
|
||||
aesdec \rdk, \blk1
|
||||
aesdec \rdk, \blk2
|
||||
aesdec \rdk, \blk3
|
||||
aesdec \rdk, \blk4
|
||||
aesdec \rdk, \blk5
|
||||
aesdec \rdk, \blk6
|
||||
aesdec \rdk, \blk7
|
||||
decl \round
|
||||
jnz .aesdec_8_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdeclast \rdk, \blk0
|
||||
aesdeclast \rdk, \blk1
|
||||
aesdeclast \rdk, \blk2
|
||||
aesdeclast \rdk, \blk3
|
||||
aesdeclast \rdk, \blk4
|
||||
aesdeclast \rdk, \blk5
|
||||
aesdeclast \rdk, \blk6
|
||||
aesdeclast \rdk, \blk7
|
||||
.endm
|
||||
|
||||
/* AES_DEC_14_BLKS */
|
||||
.macro AES_DEC_14_BLKS key round rdk blk0 blk1 blk2 blk3 blk4 blk5 blk6 blk7 blk8 blk9 blk10 blk11 blk12 blk13
|
||||
.align 16
|
||||
.aesdec_14_blks_loop:
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdec \rdk, \blk0
|
||||
aesdec \rdk, \blk1
|
||||
aesdec \rdk, \blk2
|
||||
aesdec \rdk, \blk3
|
||||
aesdec \rdk, \blk4
|
||||
aesdec \rdk, \blk5
|
||||
aesdec \rdk, \blk6
|
||||
aesdec \rdk, \blk7
|
||||
aesdec \rdk, \blk8
|
||||
aesdec \rdk, \blk9
|
||||
aesdec \rdk, \blk10
|
||||
aesdec \rdk, \blk11
|
||||
aesdec \rdk, \blk12
|
||||
aesdec \rdk, \blk13
|
||||
decl \round
|
||||
jnz .aesdec_14_blks_loop
|
||||
leaq 16(\key), \key
|
||||
movdqu (\key), \rdk
|
||||
aesdeclast \rdk, \blk0
|
||||
aesdeclast \rdk, \blk1
|
||||
aesdeclast \rdk, \blk2
|
||||
aesdeclast \rdk, \blk3
|
||||
aesdeclast \rdk, \blk4
|
||||
aesdeclast \rdk, \blk5
|
||||
aesdeclast \rdk, \blk6
|
||||
aesdeclast \rdk, \blk7
|
||||
aesdeclast \rdk, \blk8
|
||||
aesdeclast \rdk, \blk9
|
||||
aesdeclast \rdk, \blk10
|
||||
aesdeclast \rdk, \blk11
|
||||
aesdeclast \rdk, \blk12
|
||||
aesdeclast \rdk, \blk13
|
||||
.endm
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,853 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_CRYPTO_AES
|
||||
|
||||
#include "securec.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_err_internal.h"
|
||||
#include "crypt_utils.h"
|
||||
#include "crypt_errno.h"
|
||||
#include "crypt_aes.h"
|
||||
|
||||
#define TESEARCH(t0, t1, t2, t3) \
|
||||
(((uint32_t)TE2[((t0) >> 24)] & 0xff000000) ^ ((uint32_t)TE3[((t1) >> 16) & 0xff] & 0x00ff0000) ^ \
|
||||
((uint32_t)TE0[((t2) >> 8) & 0xff] & 0x0000ff00) ^ ((uint32_t)TE1[(t3) & 0xff] & 0x000000ff))
|
||||
|
||||
#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]))
|
||||
|
||||
/* Inverse S-box from 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;
|
||||
/* Query the table and perform shift. */
|
||||
ret ^= (uint32_t)TE2[(w >> 16) & 0xff] & 0xff000000;
|
||||
ret ^= (uint32_t)TE3[(w >> 8) & 0xff] & 0x00ff0000;
|
||||
ret ^= (uint32_t)TE0[(w) & 0xff] & 0x0000ff00;
|
||||
ret ^= (uint32_t)TE1[(w >> 24)] & 0x000000ff;
|
||||
ret ^= rcon;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SetEncryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key)
|
||||
{
|
||||
uint32_t *ekey = ctx->key;
|
||||
ekey[0] = GET_UINT32_BE(key, 0);
|
||||
ekey[1] = GET_UINT32_BE(key, 4);
|
||||
ekey[2] = GET_UINT32_BE(key, 8);
|
||||
ekey[3] = GET_UINT32_BE(key, 12);
|
||||
|
||||
// 128bit Key length required 11 * 4 = 44. Number of expansion rounds: 10 -> 10 * 4 + 4 = 44
|
||||
uint32_t times;
|
||||
ctx->rounds = 10;
|
||||
for (times = 0; times < 9; times++) {
|
||||
ekey[4] = AES_G(ekey[3], RCON[times]) ^ ekey[0];
|
||||
ekey[5] = ekey[4] ^ ekey[1];
|
||||
ekey[6] = ekey[5] ^ ekey[2];
|
||||
ekey[7] = ekey[6] ^ ekey[3];
|
||||
ekey += 4;
|
||||
}
|
||||
// the last time
|
||||
ekey[4] = AES_G(ekey[3], RCON[times]) ^ ekey[0];
|
||||
ekey[5] = ekey[4] ^ ekey[1];
|
||||
ekey[6] = ekey[5] ^ ekey[2];
|
||||
ekey[7] = ekey[6] ^ ekey[3];
|
||||
}
|
||||
|
||||
void SetEncryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key)
|
||||
{
|
||||
uint32_t *ekey = ctx->key;
|
||||
ekey[0] = GET_UINT32_BE(key, 0);
|
||||
ekey[1] = GET_UINT32_BE(key, 4);
|
||||
ekey[2] = GET_UINT32_BE(key, 8);
|
||||
ekey[3] = GET_UINT32_BE(key, 12);
|
||||
ekey[4] = GET_UINT32_BE(key, 16);
|
||||
ekey[5] = GET_UINT32_BE(key, 20);
|
||||
|
||||
uint32_t times;
|
||||
ctx->rounds = 12;
|
||||
|
||||
for (times = 0; times < 7; times++) {
|
||||
ekey[6] = AES_G(ekey[5], RCON[times]) ^ ekey[0];
|
||||
ekey[7] = ekey[6] ^ ekey[1];
|
||||
ekey[8] = ekey[7] ^ ekey[2];
|
||||
ekey[9] = ekey[8] ^ ekey[3];
|
||||
ekey[10] = ekey[9] ^ ekey[4];
|
||||
ekey[11] = ekey[10] ^ ekey[5];
|
||||
ekey += 6;
|
||||
}
|
||||
// the last time
|
||||
ekey[6] = AES_G(ekey[5], RCON[times]) ^ ekey[0];
|
||||
ekey[7] = ekey[6] ^ ekey[1];
|
||||
ekey[8] = ekey[7] ^ ekey[2];
|
||||
ekey[9] = ekey[8] ^ ekey[3];
|
||||
}
|
||||
|
||||
void SetEncryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key)
|
||||
{
|
||||
uint32_t *ekey = ctx->key;
|
||||
ekey[0] = GET_UINT32_BE(key, 0);
|
||||
ekey[1] = GET_UINT32_BE(key, 4);
|
||||
ekey[2] = GET_UINT32_BE(key, 8);
|
||||
ekey[3] = GET_UINT32_BE(key, 12);
|
||||
ekey[4] = GET_UINT32_BE(key, 16);
|
||||
ekey[5] = GET_UINT32_BE(key, 20);
|
||||
ekey[6] = GET_UINT32_BE(key, 24);
|
||||
ekey[7] = GET_UINT32_BE(key, 28);
|
||||
|
||||
/* The key length must be 15 * 4 = 60. The number of extension rounds is 7 -> 7 * 8 + 8 - 4 = 60 */
|
||||
uint32_t times;
|
||||
ctx->rounds = 14;
|
||||
uint32_t tmp;
|
||||
for (times = 0; times < 6; times++) {
|
||||
ekey[8] = AES_G(ekey[7], RCON[times]) ^ ekey[0];
|
||||
ekey[9] = ekey[8] ^ ekey[1];
|
||||
ekey[10] = ekey[9] ^ ekey[2];
|
||||
ekey[11] = ekey[10] ^ ekey[3];
|
||||
/* Shift operation to compensate for G operation */
|
||||
tmp = (ekey[11] >> 8) | (ekey[11] << 24);
|
||||
ekey[12] = AES_G(tmp, 0) ^ ekey[4];
|
||||
ekey[13] = ekey[12] ^ ekey[5];
|
||||
ekey[14] = ekey[13] ^ ekey[6];
|
||||
ekey[15] = ekey[14] ^ ekey[7];
|
||||
ekey += 8;
|
||||
}
|
||||
// the last time
|
||||
ekey[8] = AES_G(ekey[7], RCON[times]) ^ ekey[0];
|
||||
ekey[9] = ekey[8] ^ ekey[1];
|
||||
ekey[10] = ekey[9] ^ ekey[2];
|
||||
ekey[11] = ekey[10] ^ ekey[3];
|
||||
}
|
||||
|
||||
void SetDecryptKey(CRYPT_AES_Key *ctx)
|
||||
{
|
||||
uint32_t i, j;
|
||||
uint32_t *dkey = ctx->key;
|
||||
for (i = 1; i < ctx->rounds; i++) {
|
||||
dkey += 4;
|
||||
for (j = 0; j < 4; j++) {
|
||||
dkey[j] = TD0[TE1[(dkey[j] >> 24)] & 0xff] ^
|
||||
TD1[TE1[(dkey[j] >> 16) & 0xff] & 0xff] ^
|
||||
TD2[TE1[(dkey[j] >> 8) & 0xff] & 0xff] ^
|
||||
TD3[TE1[(dkey[j] >> 0) & 0xff] & 0xff];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetDecryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key)
|
||||
{
|
||||
SetEncryptKey128(ctx, key);
|
||||
SetDecryptKey(ctx);
|
||||
}
|
||||
|
||||
void SetDecryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key)
|
||||
{
|
||||
SetEncryptKey192(ctx, key);
|
||||
SetDecryptKey(ctx);
|
||||
}
|
||||
|
||||
void SetDecryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key)
|
||||
{
|
||||
SetEncryptKey256(ctx, key);
|
||||
SetDecryptKey(ctx);
|
||||
}
|
||||
|
||||
#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 Performs 10th and 11th rounds of calculation.
|
||||
AES_ENC_ROUND(t, c, 10, ekey);
|
||||
AES_ENC_ROUND(c, t, 11, ekey);
|
||||
}
|
||||
|
||||
if (ctx->rounds > 12) { // AES256 Performs 12th and 13th rounds of calculation.
|
||||
AES_ENC_ROUND(t, c, 12, ekey);
|
||||
AES_ENC_ROUND(c, t, 13, ekey);
|
||||
}
|
||||
|
||||
/* In the last round, the column confusion is not performed.
|
||||
Instead, the shift is performed and the s-box is searched. */
|
||||
// Do the position of the last ekey calculation, which is the ekey that has been used 4*rounds.
|
||||
ekey += ctx->rounds * 4;
|
||||
|
||||
c0 = TESEARCH(t0, t1, t2, t3) ^ ekey[0];
|
||||
c1 = TESEARCH(t1, t2, t3, t0) ^ ekey[1];
|
||||
c2 = TESEARCH(t2, t3, t0, t1) ^ ekey[2];
|
||||
c3 = TESEARCH(t3, t0, t1, t2) ^ ekey[3];
|
||||
|
||||
PUT_UINT32_BE(c0, out, 0);
|
||||
PUT_UINT32_BE(c1, out, 4);
|
||||
PUT_UINT32_BE(c2, out, 8);
|
||||
PUT_UINT32_BE(c3, out, 12);
|
||||
|
||||
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;
|
||||
uint32_t p0, p1, p2, p3, t0, t1, t2, t3;
|
||||
|
||||
// Initialize p0. The dkey starts from the end of the key.
|
||||
AES_ROUND_INIT(in, p, d);
|
||||
|
||||
dkey = ctx->key;
|
||||
|
||||
if (ctx->rounds > 12) { // AES256 Performs 12th and 13th rounds of calculation.
|
||||
AES_DEC_ROUND(p, t, 13, dkey);
|
||||
AES_DEC_ROUND(t, p, 12, dkey);
|
||||
}
|
||||
|
||||
if (ctx->rounds > 10) { // AES192 Performs 10th and 11th rounds of calculation.
|
||||
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);
|
||||
|
||||
/* In the last round, the column confusion is not performed.
|
||||
Instead, the shift is directly performed and the inverse s-box is searched. */
|
||||
p0 = INVSSEARCH(t0, t1, t2, t3) ^ dkey[0];
|
||||
p1 = INVSSEARCH(t1, t2, t3, t0) ^ dkey[1];
|
||||
p2 = INVSSEARCH(t2, t3, t0, t1) ^ dkey[2];
|
||||
p3 = INVSSEARCH(t3, t0, t1, t2) ^ dkey[3];
|
||||
|
||||
PUT_UINT32_BE(p0, out, 0);
|
||||
PUT_UINT32_BE(p1, out, 4);
|
||||
PUT_UINT32_BE(p2, out, 8);
|
||||
PUT_UINT32_BE(p3, out, 12);
|
||||
BSL_SAL_CleanseData(&p0, sizeof(uint32_t));
|
||||
BSL_SAL_CleanseData(&p1, sizeof(uint32_t));
|
||||
BSL_SAL_CleanseData(&p2, sizeof(uint32_t));
|
||||
BSL_SAL_CleanseData(&p3, sizeof(uint32_t));
|
||||
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
#endif /* HITLS_CRYPTO_AES */
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef CRYPT_AES_LOCAL_H
|
||||
#define CRYPT_AES_LOCAL_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_CRYPTO_AES
|
||||
|
||||
#include "crypt_aes.h"
|
||||
|
||||
void SetEncryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key);
|
||||
|
||||
void SetEncryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key);
|
||||
|
||||
void SetEncryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key);
|
||||
|
||||
void SetDecryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key);
|
||||
|
||||
void SetDecryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key);
|
||||
|
||||
void SetDecryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key);
|
||||
|
||||
#endif // HITLS_CRYPTO_AES
|
||||
|
||||
#endif // CRYPT_AES_LOCAL_H
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_CRYPTO_AES
|
||||
|
||||
#include "securec.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_err_internal.h"
|
||||
#include "crypt_utils.h"
|
||||
#include "crypt_errno.h"
|
||||
#include "crypt_aes_local.h"
|
||||
|
||||
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;
|
||||
}
|
||||
if (len != 16) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_AES_ERR_KEYLEN);
|
||||
return CRYPT_AES_ERR_KEYLEN;
|
||||
}
|
||||
SetEncryptKey128(ctx, key);
|
||||
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;
|
||||
}
|
||||
if (len != 24) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_AES_ERR_KEYLEN);
|
||||
return CRYPT_AES_ERR_KEYLEN;
|
||||
}
|
||||
SetEncryptKey192(ctx, key);
|
||||
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;
|
||||
}
|
||||
if (len != 32) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_AES_ERR_KEYLEN);
|
||||
return CRYPT_AES_ERR_KEYLEN;
|
||||
}
|
||||
SetEncryptKey256(ctx, key);
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t CRYPT_AES_SetDecryptKey128(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;
|
||||
}
|
||||
if (len != 16) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_AES_ERR_KEYLEN);
|
||||
return CRYPT_AES_ERR_KEYLEN;
|
||||
}
|
||||
SetDecryptKey128(ctx, key);
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t CRYPT_AES_SetDecryptKey192(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;
|
||||
}
|
||||
if (len != 24) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_AES_ERR_KEYLEN);
|
||||
return CRYPT_AES_ERR_KEYLEN;
|
||||
}
|
||||
SetDecryptKey192(ctx, key);
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t CRYPT_AES_SetDecryptKey256(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;
|
||||
}
|
||||
if (len != 32) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_AES_ERR_KEYLEN);
|
||||
return CRYPT_AES_ERR_KEYLEN;
|
||||
}
|
||||
SetDecryptKey256(ctx, key);
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
|
||||
void CRYPT_AES_Clean(CRYPT_AES_Key *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
BSL_SAL_CleanseData((void *)(ctx), sizeof(CRYPT_AES_Key));
|
||||
}
|
||||
#endif /* HITLS_CRYPTO_AES */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_CRYPTO_BN
|
||||
|
||||
#include "securec.h"
|
||||
#include "bsl_sal.h"
|
||||
#include "bsl_err_internal.h"
|
||||
#include "crypt_errno.h"
|
||||
#include "bn_bincal.h"
|
||||
#include "bn_basic.h"
|
||||
|
||||
BN_BigNum *BN_Create(uint32_t bits)
|
||||
{
|
||||
if (bits > BN_MAX_BITS) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_BN_BITS_INVALID);
|
||||
return NULL;
|
||||
}
|
||||
uint32_t room = BITS_TO_BN_UNIT(bits);
|
||||
BN_BigNum *r = (BN_BigNum *)BSL_SAL_Malloc(sizeof(BN_BigNum));
|
||||
if (r == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
|
||||
return NULL;
|
||||
}
|
||||
(void)memset_s(r, sizeof(BN_BigNum), 0, sizeof(BN_BigNum));
|
||||
if (room != 0) {
|
||||
r->room = room;
|
||||
r->data = (BN_UINT *)BSL_SAL_Malloc(room * sizeof(BN_UINT));
|
||||
if (r->data == NULL) {
|
||||
BSL_SAL_FREE(r);
|
||||
return NULL;
|
||||
}
|
||||
(void)memset_s(r->data, room * sizeof(BN_UINT), 0, room * sizeof(BN_UINT));
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void BN_Destroy(BN_BigNum *a)
|
||||
{
|
||||
if (a == NULL) {
|
||||
return;
|
||||
}
|
||||
// clear sensitive information
|
||||
BSL_SAL_CleanseData((void *)(a->data), a->size * sizeof(BN_UINT));
|
||||
BSL_SAL_FREE(a->data);
|
||||
if (!BN_IsFlag(a, CRYPT_BN_FLAG_OPTIMIZER)) {
|
||||
BSL_SAL_FREE(a);
|
||||
}
|
||||
}
|
||||
|
||||
BN_CbCtx *BN_CbCtxCreate(void)
|
||||
{
|
||||
BN_CbCtx *r = (BN_CbCtx *)BSL_SAL_Malloc(sizeof(BN_CbCtx));
|
||||
if (r == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
|
||||
return NULL;
|
||||
}
|
||||
(void)memset_s(r, sizeof(BN_CbCtx), 0, sizeof(BN_CbCtx));
|
||||
return r;
|
||||
}
|
||||
|
||||
void BN_CbCtxSet(BN_CbCtx *gencb, BN_CallBack callBack, void *arg)
|
||||
{
|
||||
if (gencb == NULL) {
|
||||
return;
|
||||
}
|
||||
BN_CbCtx *tmpCb = gencb;
|
||||
tmpCb->arg = arg;
|
||||
tmpCb->cb = callBack;
|
||||
}
|
||||
|
||||
void *BN_CbCtxGetArg(BN_CbCtx *callBack)
|
||||
{
|
||||
if (callBack == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return callBack->arg;
|
||||
}
|
||||
|
||||
int32_t BN_CbCtxCall(BN_CbCtx *callBack, int32_t process, int32_t target)
|
||||
{
|
||||
if (callBack == NULL || callBack->cb == NULL) {
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
int32_t ret = callBack->cb(callBack, process, target);
|
||||
if (ret != CRYPT_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void BN_CbCtxDestroy(BN_CbCtx *cb)
|
||||
{
|
||||
if (cb == NULL) {
|
||||
return;
|
||||
}
|
||||
BSL_SAL_FREE(cb);
|
||||
}
|
||||
|
||||
int32_t BN_SetSign(BN_BigNum *a, bool sign)
|
||||
{
|
||||
if (a == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return CRYPT_NULL_INPUT;
|
||||
}
|
||||
/* 0 must be a positive number symbol */
|
||||
if (BN_IsZero(a) == true && sign == true) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_BN_NO_NEGATIVE_ZERO);
|
||||
return CRYPT_BN_NO_NEGATIVE_ZERO;
|
||||
}
|
||||
if (sign) {
|
||||
BN_SETNEG(a->flag);
|
||||
} else {
|
||||
BN_CLRNEG(a->flag);
|
||||
}
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BN_Copy(BN_BigNum *r, const BN_BigNum *a)
|
||||
{
|
||||
if (r == NULL || a == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return CRYPT_NULL_INPUT;
|
||||
}
|
||||
if (r != a) {
|
||||
if (BnExtend(r, a->size) != CRYPT_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
|
||||
return CRYPT_MEM_ALLOC_FAIL;
|
||||
}
|
||||
BN_CLRNEG(r->flag);
|
||||
r->flag |= BN_GETNEG(a->flag);
|
||||
BN_COPY_BYTES(r->data, r->size, a->data, a->size);
|
||||
r->size = a->size;
|
||||
}
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
|
||||
BN_BigNum *BN_Dup(const BN_BigNum *a)
|
||||
{
|
||||
if (a == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
BN_BigNum *r = BN_Create(a->room * BN_UINT_BITS);
|
||||
if (r != NULL) {
|
||||
r->flag |= BN_GETNEG(a->flag);
|
||||
BN_COPY_BYTES(r->data, r->size, a->data, a->size);
|
||||
r->size = a->size;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
bool BN_IsZero(const BN_BigNum *a)
|
||||
{
|
||||
if (a == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return true;
|
||||
}
|
||||
return (a->size == 0);
|
||||
}
|
||||
|
||||
bool BN_IsOne(const BN_BigNum *a)
|
||||
{
|
||||
if (a == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return false;
|
||||
}
|
||||
return (a->size == 1 && a->data[0] == 1 && !BN_ISNEG(a->flag));
|
||||
}
|
||||
|
||||
bool BN_IsNegative(const BN_BigNum *a)
|
||||
{
|
||||
if (a == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return false;
|
||||
}
|
||||
return BN_ISNEG(a->flag);
|
||||
}
|
||||
|
||||
bool BN_IsOdd(const BN_BigNum *a)
|
||||
{
|
||||
if (a == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return false;
|
||||
}
|
||||
return (a->size > 0) && (a->data[0] & 1) != 0;
|
||||
}
|
||||
|
||||
bool BN_IsFlag(const BN_BigNum *a, uint32_t flag)
|
||||
{
|
||||
if (a == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return false;
|
||||
}
|
||||
return a->flag & flag;
|
||||
}
|
||||
|
||||
int32_t BN_Zeroize(BN_BigNum *a)
|
||||
{
|
||||
if (a == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return CRYPT_NULL_INPUT;
|
||||
}
|
||||
// clear sensitive information
|
||||
BSL_SAL_CleanseData(a->data, a->size * sizeof(BN_UINT));
|
||||
BN_CLRNEG(a->flag);
|
||||
a->size = 0;
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
|
||||
bool BN_IsLimb(const BN_BigNum *a, const BN_UINT w)
|
||||
{
|
||||
if (a == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return (w == 0);
|
||||
}
|
||||
return ((a->size == 1) && (a->data[0] == w)) || ((w == 0) && (a->size == 0));
|
||||
}
|
||||
|
||||
int32_t BN_SetLimb(BN_BigNum *r, BN_UINT w)
|
||||
{
|
||||
if (r == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return CRYPT_NULL_INPUT;
|
||||
}
|
||||
if (BnExtend(r, 1) != CRYPT_SUCCESS) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
|
||||
return CRYPT_MEM_ALLOC_FAIL;
|
||||
}
|
||||
BN_Zeroize(r);
|
||||
if (w != 0) {
|
||||
r->data[r->size] = w;
|
||||
r->size++;
|
||||
}
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
|
||||
bool BN_GetBit(const BN_BigNum *a, uint32_t n)
|
||||
{
|
||||
if (a == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return false;
|
||||
}
|
||||
uint32_t nw = n / BN_UINT_BITS;
|
||||
uint32_t nb = n % BN_UINT_BITS;
|
||||
if (nw >= a->size) {
|
||||
return false;
|
||||
}
|
||||
return (uint32_t)(((a->data[nw]) >> nb) & ((BN_UINT)1));
|
||||
}
|
||||
|
||||
int32_t BN_SetBit(BN_BigNum *a, uint32_t n)
|
||||
{
|
||||
if (a == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return CRYPT_NULL_INPUT;
|
||||
}
|
||||
uint32_t nw = n / BN_UINT_BITS;
|
||||
uint32_t nb = n % BN_UINT_BITS;
|
||||
if (nw >= a->room) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_BN_SPACE_NOT_ENOUGH);
|
||||
return CRYPT_BN_SPACE_NOT_ENOUGH;
|
||||
}
|
||||
a->data[nw] |= (((BN_UINT)1) << nb);
|
||||
if (a->size < nw + 1) {
|
||||
a->size = nw + 1;
|
||||
}
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t BN_ClrBit(BN_BigNum *a, uint32_t n)
|
||||
{
|
||||
if (a == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return CRYPT_NULL_INPUT;
|
||||
}
|
||||
uint32_t nw = n / BN_UINT_BITS;
|
||||
uint32_t nb = n % BN_UINT_BITS;
|
||||
if (nw >= a->size) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_BN_SPACE_NOT_ENOUGH);
|
||||
return CRYPT_BN_SPACE_NOT_ENOUGH;
|
||||
}
|
||||
a->data[nw] &= (~(((BN_UINT)1) << nb));
|
||||
// check whether the size changes
|
||||
a->size = BinFixSize(a->data, a->size);
|
||||
if (a->size == 0) {
|
||||
BN_CLRNEG(a->flag);
|
||||
}
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t BN_Bits(const BN_BigNum *a)
|
||||
{
|
||||
if (a == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
|
||||
return 0;
|
||||
}
|
||||
if (a->size == 0) {
|
||||
return 0;
|
||||
}
|
||||
return BinBits(a->data, a->size);
|
||||
}
|
||||
|
||||
uint32_t BN_Bytes(const BN_BigNum *a)
|
||||
{
|
||||
return BN_BITS_TO_BYTES(BN_Bits(a));
|
||||
}
|
||||
|
||||
uint32_t BnExtend(BN_BigNum *a, uint32_t words)
|
||||
{
|
||||
if (a->room >= words) {
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
if (words > BITS_TO_BN_UNIT(BN_MAX_BITS)) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_BN_BITS_TOO_MAX);
|
||||
return CRYPT_BN_BITS_TOO_MAX;
|
||||
}
|
||||
|
||||
BN_UINT *tmp = (BN_UINT *)BSL_SAL_Malloc(words * sizeof(BN_UINT));
|
||||
if (tmp == NULL) {
|
||||
BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
|
||||
return CRYPT_MEM_ALLOC_FAIL;
|
||||
}
|
||||
(void)memset_s(tmp, words * sizeof(BN_UINT), 0, words * sizeof(BN_UINT));
|
||||
if (a->data != NULL) {
|
||||
(void)memcpy_s(tmp, a->size * sizeof(BN_UINT), a->data, a->size * sizeof(BN_UINT));
|
||||
BSL_SAL_CleanseData(a->data, a->size * sizeof(BN_UINT));
|
||||
BSL_SAL_FREE(a->data);
|
||||
}
|
||||
a->data = tmp;
|
||||
a->room = words;
|
||||
return CRYPT_SUCCESS;
|
||||
}
|
||||
|
||||
/* See the standard document
|
||||
* https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r4.pdf
|
||||
* Table 2: Comparable strengths
|
||||
* */
|
||||
int32_t BN_SecBit(int32_t publen, int32_t prvlen)
|
||||
{
|
||||
int32_t bits = 256;
|
||||
int32_t level[] = {1024, 2048, 3072, 7680, 15360, INT32_MAX};
|
||||
int32_t secbits[] = {0, 80, 112, 128, 192, 256};
|
||||
|
||||
for (size_t i = 0; i < (sizeof(level) / sizeof(level[0])); i++) {
|
||||
if (publen < level[i]) {
|
||||
bits = secbits[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (prvlen == -1) {
|
||||
return bits;
|
||||
}
|
||||
bits = ((prvlen / 2) >= bits) ? bits : (prvlen / 2);
|
||||
return (bits < 80) ? 0 : bits;
|
||||
}
|
||||
#endif /* HITLS_CRYPTO_BN */
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef BN_BASIC_H
|
||||
#define BN_BASIC_H
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_CRYPTO_BN
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "crypt_bn.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BN_UINT_BITS ((uint32_t)sizeof(BN_UINT) << 3)
|
||||
#define BITS_TO_BN_UNIT(bits) (((bits) + BN_UINT_BITS - 1) / BN_UINT_BITS)
|
||||
#define BITS_TO_BYTES(bits) (((bits) + 7) / 8)
|
||||
#define BN_CLRNEG(n) ((n) &= 0x7FFFFFFF)
|
||||
#define BN_SETNEG(n) ((n) |= CRYPT_BN_FLAG_ISNEGTIVE)
|
||||
#define BN_ISNEG(n) (((n) & CRYPT_BN_FLAG_ISNEGTIVE) != 0)
|
||||
#define BN_GETNEG(n) ((n) & CRYPT_BN_FLAG_ISNEGTIVE)
|
||||
|
||||
struct BigNum {
|
||||
uint32_t size; /* *< BigNum size (count of BN_UINT) */
|
||||
uint32_t room; /* *< BigNum max size (count of BN_UINT) */
|
||||
uint32_t flag; /* *< BigNum flag */
|
||||
BN_UINT *data; /* *< BigNum data chunk(most significant limb at the largest) */
|
||||
};
|
||||
|
||||
struct BnMont {
|
||||
uint32_t mSize; /* *< size of mod in BN_UINT */
|
||||
BN_UINT k0; /* *< low word of (1/(r - mod[0])) mod r */
|
||||
BN_UINT *mod; /* *< mod */
|
||||
BN_UINT *montRR; /* *< mont_enc(1) */
|
||||
BN_UINT *b; /* *< tmpb(1) */
|
||||
BN_UINT *t; /* *< tmpt(1) ^ 2 */
|
||||
};
|
||||
|
||||
struct BnCbCtx {
|
||||
void *arg; // callback parameter
|
||||
BN_CallBack cb; // callback function, which is defined by the user
|
||||
};
|
||||
|
||||
/* Find a pointer address aligned by 'alignment' bytes in the [ptr, ptr + alignment - 1] range.
|
||||
The input parameter alignment cannot be 0. */
|
||||
static inline BN_UINT *AlignedPointer(const void *ptr, uintptr_t alignment)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)(uintptr_t)ptr + alignment - 1;
|
||||
return (BN_UINT *)((uintptr_t)p - (uintptr_t)p % alignment);
|
||||
}
|
||||
|
||||
uint32_t BnExtend(BN_BigNum *a, uint32_t words);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // HITLS_CRYPTO_BN
|
||||
|
||||
#endif // BN_BASIC_H
|
||||
@@ -0,0 +1,441 @@
|
||||
/*
|
||||
* This file is part of the openHiTLS project.
|
||||
*
|
||||
* openHiTLS is licensed under the Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "hitls_build.h"
|
||||
#ifdef HITLS_CRYPTO_BN
|
||||
|
||||
#include <stdint.h>
|
||||
#include "securec.h"
|
||||
#include "bn_bincal.h"
|
||||
|
||||
/* r = a + b, the length of r, a and b array is n. The return value is the carry. */
|
||||
BN_UINT BinAdd(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n)
|
||||
{
|
||||
BN_UINT carry = 0;
|
||||
uint32_t nn = n;
|
||||
const BN_UINT *aa = a;
|
||||
const BN_UINT *bb = b;
|
||||
BN_UINT *rr = r;
|
||||
while (nn >= 4) {
|
||||
ADD_ABC(carry, rr[0], aa[0], bb[0], carry);
|
||||
ADD_ABC(carry, rr[1], aa[1], bb[1], carry);
|
||||
ADD_ABC(carry, rr[2], aa[2], bb[2], carry);
|
||||
ADD_ABC(carry, rr[3], aa[3], bb[3], carry);
|
||||
rr += 4;
|
||||
aa += 4;
|
||||
bb += 4;
|
||||
nn -= 4;
|
||||
}
|
||||
uint32_t i = 0;
|
||||
for (; i < nn; i++) {
|
||||
ADD_ABC(carry, rr[i], aa[i], bb[i], carry);
|
||||
}
|
||||
return carry;
|
||||
}
|
||||
|
||||
/* r = a - b, the length of r, a and b array is n. The return value is the borrow-digit. */
|
||||
BN_UINT BinSub(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n)
|
||||
{
|
||||
BN_UINT borrow = 0;
|
||||
uint32_t nn = n;
|
||||
const BN_UINT *aa = a;
|
||||
const BN_UINT *bb = b;
|
||||
BN_UINT *rr = r;
|
||||
while (nn >= 4) {
|
||||
SUB_ABC(borrow, rr[0], aa[0], bb[0], borrow);
|
||||
SUB_ABC(borrow, rr[1], aa[1], bb[1], borrow);
|
||||
SUB_ABC(borrow, rr[2], aa[2], bb[2], borrow);
|
||||
SUB_ABC(borrow, rr[3], aa[3], bb[3], borrow);
|
||||
rr += 4;
|
||||
aa += 4;
|
||||
bb += 4;
|
||||
nn -= 4;
|
||||
}
|
||||
uint32_t i = 0;
|
||||
for (; i < nn; i++) {
|
||||
SUB_ABC(borrow, rr[i], aa[i], bb[i], borrow);
|
||||
}
|
||||
return borrow;
|
||||
}
|
||||
|
||||
/* r = a + w, the length of r and a array is 'size'. The return value is the carry. */
|
||||
BN_UINT BinInc(BN_UINT *r, const BN_UINT *a, uint32_t size, BN_UINT w)
|
||||
{
|
||||
uint32_t i;
|
||||
BN_UINT carry = w;
|
||||
for (i = 0; i < size && carry != 0; i++) {
|
||||
ADD_AB(carry, r[i], a[i], carry);
|
||||
}
|
||||
if (r != a) {
|
||||
for (; i < size; i++) {
|
||||
r[i] = a[i];
|
||||
}
|
||||
}
|
||||
|
||||
return carry;
|
||||
}
|
||||
|
||||
/* r = a - w, the length of r and a array is 'size'. The return value is the borrow-digit. */
|
||||
BN_UINT BinDec(BN_UINT *r, const BN_UINT *a, uint32_t n, BN_UINT w)
|
||||
{
|
||||
uint32_t i;
|
||||
BN_UINT borrow = w;
|
||||
for (i = 0; (i < n) && (borrow > 0); i++) {
|
||||
SUB_AB(borrow, r[i], a[i], borrow);
|
||||
}
|
||||
if (r != a) {
|
||||
for (; i < n; i++) {
|
||||
r[i] = a[i];
|
||||
}
|
||||
}
|
||||
return borrow;
|
||||
}
|
||||
|
||||
/* r = a >> bits, the return value is the valid length of r after the shift.
|
||||
* The array length of a is n. The length of the r array must meet the requirements of the accepted calculation result,
|
||||
* which is guaranteed by the input parameter.
|
||||
*/
|
||||
uint32_t BinRshift(BN_UINT *r, const BN_UINT *a, uint32_t n, uint32_t bits)
|
||||
{
|
||||
uint32_t nw = bits / BN_UINT_BITS; /* shift words */
|
||||
uint32_t nb = bits % BN_UINT_BITS; /* shift bits */
|
||||
/**
|
||||
* unsigned shift operand cannot be greater than or equal to the data bit width
|
||||
* Otherwise, undefined behavior is triggered.
|
||||
*/
|
||||
uint32_t na = (BN_UINT_BITS - nb) % BN_UINT_BITS;
|
||||
uint32_t rsize = n - nw;
|
||||
uint32_t i;
|
||||
BN_UINT hi;
|
||||
BN_UINT lo = a[nw];
|
||||
/* When nb == 0, discard the value of (hi << na) with the all-zero mask. */
|
||||
BN_UINT mask = ~BN_IsZeroUintConsttime(nb);
|
||||
/* Assigns values from the lower bits. */
|
||||
for (i = nw; i < n - 1; i++) {
|
||||
hi = a[i + 1];
|
||||
r[i - nw] = (lo >> nb) | ((hi << na) & mask);
|
||||
lo = hi;
|
||||
}
|
||||
lo >>= nb;
|
||||
if (lo != 0) {
|
||||
r[rsize - 1] = lo;
|
||||
} else {
|
||||
rsize--;
|
||||
}
|
||||
return rsize;
|
||||
}
|
||||
|
||||
/* r = a << bits. The return value is the valid length of r after the shift.
|
||||
* The array length of a is n. The length of the r array must meet the requirements of the accepted calculation result,
|
||||
* which is guaranteed by the input parameter.
|
||||
*/
|
||||
uint32_t BinLshift(BN_UINT *r, const BN_UINT *a, uint32_t n, uint32_t bits)
|
||||
{
|
||||
uint32_t nw = bits / BN_UINT_BITS; /* shift words */
|
||||
uint32_t nb = bits % BN_UINT_BITS; /* shift bits */
|
||||
/**
|
||||
* unsigned shift operand cannot be greater than or equal to the data bit width
|
||||
* Otherwise, undefined behavior is triggered.
|
||||
*/
|
||||
uint32_t na = (BN_UINT_BITS - nb) % BN_UINT_BITS;
|
||||
uint32_t rsize = n + nw;
|
||||
uint32_t i;
|
||||
BN_UINT hi = a[n - 1];
|
||||
BN_UINT lo;
|
||||
/* When nb == 0, discard the value of (hi << na) with the all-zero mask. */
|
||||
BN_UINT mask = ~BN_IsZeroUintConsttime(nb);
|
||||
lo = (hi >> na) & mask;
|
||||
/* Assign a value to the most significant bit. */
|
||||
if (lo != 0) {
|
||||
r[rsize++] = lo;
|
||||
}
|
||||
/* Assign a value from the most significant bits. */
|
||||
for (i = n - 1; i > 0; i--) {
|
||||
lo = a[i - 1];
|
||||
r[i + nw] = (hi << nb) | ((lo >> na) & mask);
|
||||
hi = lo;
|
||||
}
|
||||
r[nw] = a[0] << nb;
|
||||
/* Clear the lower bits to 0. */
|
||||
if (nw != 0) {
|
||||
(void)memset_s(r, nw * sizeof(BN_UINT), 0, nw * sizeof(BN_UINT));
|
||||
}
|
||||
|
||||
return rsize;
|
||||
}
|
||||
|
||||
/* r = a * b + r. The return value is a carry. */
|
||||
BN_UINT BinMulAcc(BN_UINT *r, const BN_UINT *a, uint32_t aSize, BN_UINT b)
|
||||
{
|
||||
BN_UINT c = 0;
|
||||
BN_UINT *rr = r;
|
||||
const BN_UINT *aa = a;
|
||||
uint32_t size = aSize;
|
||||
while (size >= 4) {
|
||||
MULADD_ABC(c, rr[0], aa[0], b);
|
||||
MULADD_ABC(c, rr[1], aa[1], b);
|
||||
MULADD_ABC(c, rr[2], aa[2], b);
|
||||
MULADD_ABC(c, rr[3], aa[3], b);
|
||||
aa += 4;
|
||||
rr += 4;
|
||||
size -= 4;
|
||||
}
|
||||
while (size > 0) {
|
||||
MULADD_ABC(c, rr[0], aa[0], b);
|
||||
aa++;
|
||||
rr++;
|
||||
size--;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/* r = a * b rRoom >= aSize + bSize. The length is guaranteed by the input parameter. r != a, r != b.
|
||||
* The return value is the valid length of the result. */
|
||||
uint32_t BinMul(BN_UINT *r, uint32_t rRoom, const BN_UINT *a, uint32_t aSize, const BN_UINT *b, uint32_t bSize)
|
||||
{
|
||||
BN_UINT carry = 0;
|
||||
uint32_t i, j;
|
||||
(void)memset_s(r, rRoom * sizeof(BN_UINT), 0, rRoom * sizeof(BN_UINT));
|
||||
/* Result combination of cyclic calculation data units. */
|
||||
for (i = 0; i < bSize; i++) {
|
||||
BN_UINT t = b[i];
|
||||
for (j = 0, carry = 0; j < aSize; j++) {
|
||||
BN_UINT rh, rl;
|
||||
MUL_AB(rh, rl, a[j], t);
|
||||
ADD_ABC(carry, r[i + j], r[i + j], rl, carry);
|
||||
carry += rh;
|
||||
}
|
||||
if (carry != 0) {
|
||||
r[i + j] = carry;
|
||||
}
|
||||
}
|
||||
return aSize + bSize - (carry == 0);
|
||||
}
|
||||
|
||||
/* r = a * a rRoom >= aSize * 2. The length is guaranteed by the input parameter. r != a.
|
||||
* The return value is the valid length of the result. */
|
||||
uint32_t BinSqr(BN_UINT *r, uint32_t rRoom, const BN_UINT *a, uint32_t aSize)
|
||||
{
|
||||
uint32_t i;
|
||||
BN_UINT carry;
|
||||
BN_UINT rh, rl;
|
||||
|
||||
(void)memset_s(r, rRoom * sizeof(BN_UINT), 0, rRoom * sizeof(BN_UINT));
|
||||
if (aSize < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Calculate unequal data units, similar to trapezoid. */
|
||||
for (i = 0; i < aSize - 1; i++) {
|
||||
BN_UINT t = a[i];
|
||||
uint32_t j;
|
||||
for (j = i + 1, carry = 0; j < aSize; j++) {
|
||||
MUL_AB(rh, rl, a[j], t);
|
||||
ADD_ABC(carry, r[i + j], rl, r[i + j], carry);
|
||||
carry += rh;
|
||||
}
|
||||
r[i + j] = carry;
|
||||
}
|
||||
/* In the square, the multiplier unit is symmetrical. r = r * 2 */
|
||||
BinLshift(r, r, 2 * aSize - 1, 1);
|
||||
/* Calculate the direct squared data unit and add it to the result. */
|
||||
for (i = 0, carry = 0; i < aSize; i++) {
|
||||
SQR_A(rh, rl, a[i]);
|
||||
ADD_ABC(carry, r[i << 1], r[i << 1], rl, carry);
|
||||
ADD_ABC(carry, r[(i << 1) + 1], r[(i << 1) + 1], rh, carry);
|
||||
}
|
||||
return aSize + aSize - (r[(aSize << 1) - 1] == 0);
|
||||
}
|
||||
|
||||
/* Obtains the number of 0s in the first x most significant bits of data. */
|
||||
uint32_t GetZeroBitsUint(BN_UINT x)
|
||||
{
|
||||
BN_UINT t = x;
|
||||
BN_UINT mask;
|
||||
uint32_t bits = 0;
|
||||
uint32_t base = BN_UINT_BITS >> 1;
|
||||
BN_UINT m = (BN_UINT)(-1);
|
||||
uint32_t shift = BN_UINT_BITS >> 1;
|
||||
/* dichotomy */
|
||||
do {
|
||||
m <<= shift;
|
||||
mask = BN_IsZeroUintConsttime(t & m); /* Check whether the upper half part is valid. */
|
||||
bits += base & (uint32_t)mask;
|
||||
t = ((t << shift) & mask) | (t & ~mask); /* Select the all upper or lower part of t based on the mask value. */
|
||||
shift >>= 1;
|
||||
base >>= 1; /* dichotomy, reduce the scope to 1/2 of each inspection */
|
||||
} while (shift > 0);
|
||||
|
||||
mask = BN_IsZeroUintConsttime(t & m);
|
||||
bits += 1 & mask;
|
||||
return bits;
|
||||
}
|
||||
|
||||
/* refresh the size */
|
||||
uint32_t BinFixSize(const BN_UINT *data, uint32_t size)
|
||||
{
|
||||
uint32_t fix = size;
|
||||
uint32_t i = size;
|
||||
BN_UINT m = (BN_UINT)(-1);
|
||||
for (; i > 0; i--) {
|
||||
m &= BN_IsZeroUintConsttime(data[i - 1]);
|
||||
fix -= 1 & m;
|
||||
}
|
||||
return fix;
|
||||
}
|
||||
|
||||
/* compare */
|
||||
int32_t BinCmp(const BN_UINT *a, uint32_t aSize, const BN_UINT *b, uint32_t bSize)
|
||||
{
|
||||
if (aSize == bSize) {
|
||||
uint32_t len = aSize;
|
||||
|
||||
while (len > 0) {
|
||||
len--;
|
||||
if (a[len] != b[len]) {
|
||||
return a[len] > b[len] ? 1 : -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return aSize > bSize ? 1 : -1;
|
||||
}
|
||||
|
||||
/* obtain bits */
|
||||
uint32_t BinBits(const BN_UINT *data, uint32_t size)
|
||||
{
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
return (size * BN_UINT_BITS - GetZeroBitsUint(data[size - 1]));
|
||||
}
|
||||
|
||||
/* Multiply and then subtract. The return value is borrow digit. */
|
||||
static BN_UINT BinSubMul(BN_UINT *r, const BN_UINT *a, uint32_t aSize, BN_UINT m)
|
||||
{
|
||||
BN_UINT borrow = 0;
|
||||
uint32_t i;
|
||||
for (i = 0; i < aSize; i++) {
|
||||
BN_UINT ah, al;
|
||||
MUL_AB(ah, al, a[i], m);
|
||||
SUB_ABC(borrow, r[i], r[i], al, borrow);
|
||||
borrow += ah;
|
||||
}
|
||||
|
||||
return borrow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to reduce the borrowing cost, guarantee h|l >= q * yl. If q is too large, reduce q.
|
||||
* Each time q decreases by 1, h increases by yh. y was previously offset, and the most significant bit of yh is 1.
|
||||
* Therefore (q * yl << BN_UINT_BITS) < (yh * 2), number of borrowing times ≤ 2.
|
||||
*/
|
||||
static BN_UINT TryDiv(BN_UINT q, BN_UINT h, BN_UINT l, BN_UINT yh, BN_UINT yl)
|
||||
{
|
||||
BN_UINT rh, rl;
|
||||
MUL_AB(rh, rl, q, yl);
|
||||
/* Compare h|l >= rh|rl. Otherwise, reduce q. */
|
||||
if (rh < h || (rh == h && rl <= l)) {
|
||||
return q;
|
||||
}
|
||||
BN_UINT nq = q - 1;
|
||||
BN_UINT nh = h + yh;
|
||||
/* If carry occurs, no judgment is required. */
|
||||
if (nh < yh) {
|
||||
return nq;
|
||||
}
|
||||
/* rh|rl - yl */
|
||||
if (rl < yl) {
|
||||
rh--;
|
||||
}
|
||||
rl -= yl;
|
||||
|
||||
/* Compare r|l >= rh|rl. Otherwise, reduce q. */
|
||||
if (rh < nh || (rh == nh && rl <= l)) {
|
||||
return nq;
|
||||
}
|
||||
nq--;
|
||||
return nq;
|
||||
}
|
||||
|
||||
/* Divide core operation */
|
||||
static void BinDivCore(BN_UINT *q, uint32_t *qSize, BN_UINT *x, uint32_t xSize, const BN_UINT *y, uint32_t ySize)
|
||||
{
|
||||
BN_UINT yy = y[ySize - 1]; /* Obtain the most significant bit of the data. */
|
||||
uint32_t i;
|
||||
for (i = xSize; i >= ySize; i--) {
|
||||
BN_UINT qq;
|
||||
if (x[i] == yy) {
|
||||
qq = (BN_UINT)-1;
|
||||
} else {
|
||||
BN_UINT rr;
|
||||
DIV_ND(qq, rr, x[i], x[i - 1], yy);
|
||||
if (ySize > 1) { /* If ySize is 1, do not need to try divide. */
|
||||
/* Obtain the least significant bit data, that is, make subscript - 2. */
|
||||
qq = TryDiv(qq, rr, x[i - 2], yy, y[ySize - 2]);
|
||||
}
|
||||
}
|
||||
if (qq > 0) {
|
||||
/* After the TryDiv is complete, perform the double subtraction. */
|
||||
BN_UINT extend = BinSubMul(&x[i - ySize], y, ySize, qq);
|
||||
extend = (x[i] -= extend);
|
||||
if (extend > 0) {
|
||||
/* reverse, borrowing required */
|
||||
extend = BinAdd(&x[i - ySize], &x[i - ySize], y, ySize);
|
||||
x[i] += extend;
|
||||
qq--;
|
||||
}
|
||||
if (q != NULL && qq != 0) {
|
||||
/* update quotient */
|
||||
q[i - ySize] = qq;
|
||||
*qSize = (*qSize) > (i - ySize + 1) ? (*qSize) : (i - ySize + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* x / y = q...x, the return value is the updated xSize.
|
||||
* q and asize are both NULL or not NULL. Other input parameters must be valid.
|
||||
* q, x and y cannot be the same pointer.
|
||||
* Ensure that x->room >= xSize + 2, and the extra two spaces need to be cleared. Extra space is used during try divide.
|
||||
*/
|
||||
uint32_t BinDiv(BN_UINT *q, uint32_t *qSize, BN_UINT *x, uint32_t xSize, BN_UINT *y, uint32_t ySize)
|
||||
{
|
||||
if (q != NULL) {
|
||||
(void)memset_s(q, *qSize * sizeof(BN_UINT), 0, *qSize * sizeof(BN_UINT));
|
||||
*qSize = 0;
|
||||
}
|
||||
if (xSize < ySize) {
|
||||
return xSize;
|
||||
}
|
||||
uint32_t shifts = GetZeroBitsUint(y[ySize - 1]);
|
||||
BN_UINT xNewSize = xSize;
|
||||
BN_UINT yNewSize = ySize;
|
||||
/* Left shift until the maximum displacement of the divisor is full. */
|
||||
if (shifts != 0) {
|
||||
xNewSize = BinLshift(x, x, xSize, shifts);
|
||||
yNewSize = BinLshift(y, y, ySize, shifts);
|
||||
}
|
||||
BinDivCore(q, qSize, x, xSize, y, ySize);
|
||||
/* shift compensation */
|
||||
if (shifts != 0) {
|
||||
xNewSize = (BN_UINT)BinRshift(x, x, (uint32_t)xNewSize, shifts);
|
||||
yNewSize = (BN_UINT)BinRshift(y, y, (uint32_t)yNewSize, shifts);
|
||||
(void)yNewSize;
|
||||
}
|
||||
return BinFixSize(x, (uint32_t)xNewSize);
|
||||
}
|
||||
#endif /* HITLS_CRYPTO_BN */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user