openhitls repo init

This commit is contained in:
fly2x
2024-10-15 10:02:41 +08:00
commit be2fc52601
1417 changed files with 325434 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
.vscode
build
__pycache__
*/build/*
testcode/framework/tls/lib/
testcode/output/
platform/*
+3
View File
@@ -0,0 +1,3 @@
[submodule "platform/Secure_C"]
path = platform/Secure_C
url = https://gitee.com/openeuler/libboundscheck.git
+28
View File
@@ -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)
+125
View File
@@ -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 LicenseVersion 2
Mulan Permissive Software LicenseVersion 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 ITS 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 LicenseVersion 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
View File
@@ -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、TLCPAESSM4Chacha20RSADSAECDSAECDHDHSM2DRBGHKDFSCRYPTPBKDF2SHA2SHA3MD5SM3HMACX509
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_CSecure 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签署。
+99
View File
@@ -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.
+819
View File
@@ -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.
+286
View File
@@ -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
+54
View File
@@ -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
+66
View File
@@ -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 */
+587
View File
@@ -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 */
+65
View File
@@ -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
+296
View File
@@ -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 */
+120
View File
@@ -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
+534
View File
@@ -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 */
+388
View File
@@ -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
+349
View File
@@ -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
+300
View File
@@ -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
+664
View File
@@ -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 */
+367
View File
@@ -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 */
+45
View File
@@ -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 */
+48
View File
@@ -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 */
+334
View File
@@ -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 */
+44
View File
@@ -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
+207
View File
@@ -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
+118
View File
@@ -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
+33
View File
@@ -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 */
+92
View File
@@ -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
+569
View File
@@ -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 */
+170
View File
@@ -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 */
+214
View File
@@ -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 */
+110
View File
@@ -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
+99
View File
@@ -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 */
+70
View File
@@ -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
+77
View File
@@ -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
+264
View File
@@ -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
+75
View File
@@ -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 */
+207
View File
@@ -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 */
+38
View File
@@ -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
+135
View File
@@ -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
+61
View File
@@ -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
+53
View File
@@ -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
+100
View File
@@ -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
+102
View File
@@ -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
+208
View File
@@ -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
+35
View File
@@ -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
+133
View File
@@ -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
+63
View File
@@ -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
+104
View File
@@ -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
+31
View File
@@ -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);
}
+62
View File
@@ -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;
}
}
+142
View File
@@ -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
+52
View File
@@ -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
+49
View File
@@ -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
+239
View File
@@ -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
+38
View File
@@ -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
+211
View File
@@ -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
+70
View File
@@ -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
+135
View File
@@ -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;
}
+431
View File
@@ -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 */
+57
View File
@@ -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
+90
View File
@@ -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
+150
View File
@@ -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 */
+55
View File
@@ -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
+559
View File
@@ -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 */
+74
View File
@@ -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
+232
View File
@@ -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 */
+540
View File
@@ -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, &parameters->shareKeyId, sizeof(parameters->shareKeyId));
case BSL_UIO_SCTP_DEL_PRE_AUTH_SHARED_KEY:
return BslSctpDelAuthKey(uio, &parameters->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), &parameters->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 */
+40
View File
@@ -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
+220
View File
@@ -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 */
+37
View File
@@ -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
+110
View File
@@ -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 */
+46
View File
@@ -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": []
}
}
+200
View File
@@ -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"
]
}
}
+715
View File
@@ -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"]
}
}
}
}
+22
View File
@@ -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 */
+52
View File
@@ -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 */
+429
View File
@@ -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
View File
@@ -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)
+217
View File
@@ -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
+428
View File
@@ -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 v2128bit.
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
+482
View File
@@ -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.
* blockinput the plaintext.
* key: One round key.
*/
.macro ROUND block, key
aese \block, \key
aesmc \block, \block
.endm
/*
* Eight blocks of decryption.
* block0_7Input 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:
* x0Pointer to the input key structure
* x1points to the input data address
* x2points to the output data address
* x3Length of the input data, which must be a multiple of 16
* x4Points to the CBC mode mask address
* Change registerx5, x6, v0-v31
* Output registerx0
* 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
* x0pointer to the input key structure
* x1points to the input data address
* x2points to the output data address
* x3Length of the input data, which must be a multiple of 16
* x4Points to the CBC mode mask address
* Change registerx5, x6, v0-v31
* Output registerx0
* 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
+499
View File
@@ -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 descriptionAES encrypted assembly acceleration API in CBC mode.
* Function prototypeint32_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
* rdipointer to the input key structure
* rsipoints to the input data address
* rdxpoints to the output data address
* rcxLength of the input data, which must be a multiple of 16
* r8 Points to the CBC mode mask address
* Change registerxmm0-xmm15
* Output registereax
* 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 prototypeint32_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:
* rdipointer to the input key structure
* rsipoints to the input data address.
* rdxpoints to the output data address.
* rcxLength of the input data, which must be a multiple of 16
* r8 Points to the CBC mode mask address
* Change registerxmm0-xmm13
* Output registereax
* 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
+297
View File
@@ -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
+353
View File
@@ -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
+588
View File
@@ -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
* ctr32Initialization vector.
* offsetOffset.
* temp32-bit CTR temporary register.
* key3232-bit round key.
* addrOffsetpush stack address offset.
* addrpush 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
* Inputpointer to the input memory.
* Outputpointer to the output memory.
* Lenremaining data length.
* Offsetindicates 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 descriptionSets the AES encrypted assembly acceleration API, ctr mode.
* Function prototypeint32_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
* rdiPointer to the input key structure.
* rsiPoints to the 128-bit input data.
* rdxPoints to the 128-bit output data.
* rcxLength of the data block, that is, 16 bytes.
* r8: 16-byte initialization vector.
* Change registerxmm1, xmm3, xmm4, xmm5, xmm6, xmm10, xmm11, xmm12, xmm13.
* Output registerrdx, 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
+304
View File
@@ -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
+548
View File
@@ -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
+951
View File
@@ -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
+438
View File
@@ -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
+853
View File
@@ -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 */
+38
View File
@@ -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
+117
View File
@@ -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
+370
View File
@@ -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 */
+74
View File
@@ -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
+441
View File
@@ -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